package com.itaming.lycheeframework.support.utils;

import com.itaming.lycheeframework.support.lambda.SerializableLambda;
import com.itaming.lycheeframework.support.lambda.function.*;
import com.itaming.lycheeframework.support.lambda.predicate.*;
import lombok.experimental.UtilityClass;
import org.springframework.util.Assert;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.function.DoublePredicate;
import java.util.function.IntPredicate;
import java.util.function.LongPredicate;
import java.util.function.Predicate;

/**
 * Array工具类
 *
 * @author A.Ming
 */
@UtilityClass
public class ArrayUtil {

    /**
     * 空数组
     */
    public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
    public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];
    public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
    public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];
    public static final char[] EMPTY_CHAR_ARRAY = new char[0];
    public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
    public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
    public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];
    public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
    public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];
    public static final int[] EMPTY_INT_ARRAY = new int[0];
    public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
    public static final long[] EMPTY_LONG_ARRAY = new long[0];
    public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];
    public static final short[] EMPTY_SHORT_ARRAY = new short[0];
    public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];
    public static final String[] EMPTY_STRING_ARRAY = new String[0];
    public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
    public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0];
    public static final Method[] EMPTY_METHOD_ARRAY = new Method[0];
    public static final Field[] EMPTY_FIELD_ARRAY = new Field[0];

    /**
     * 创建指定长度的数组并填充
     *
     * @param length 长度
     * @param value  填充值
     * @return 创建的数组
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] newArray(int length, T value) {
        Assert.notNull(value, "Fill value must not be null");
        T[] array = (T[]) Array.newInstance(value.getClass(), length);
        Arrays.fill(array, value);
        return array;
    }

    /**
     * 创建指定长度的数组并填充
     *
     * @param length 长度
     * @param value  填充值
     * @return 创建的数组
     */
    public static boolean[] newArray(int length, boolean value) {
        if (length <= 0) {
            return EMPTY_BOOLEAN_ARRAY;
        }

        boolean[] array = new boolean[length];
        Arrays.fill(array, value);
        return array;
    }

    /**
     * 创建指定长度的数组并填充
     *
     * @param length 长度
     * @param value  填充值
     * @return 创建的数组
     */
    public static byte[] newArray(int length, byte value) {
        if (length <= 0) {
            return EMPTY_BYTE_ARRAY;
        }

        byte[] array = new byte[length];
        Arrays.fill(array, value);
        return array;
    }

    /**
     * 创建指定长度的数组并填充
     *
     * @param length 长度
     * @param value  填充值
     * @return 创建的数组
     */
    public static char[] newArray(int length, char value) {
        if (length <= 0) {
            return EMPTY_CHAR_ARRAY;
        }

        char[] array = new char[length];
        Arrays.fill(array, value);
        return array;
    }

    /**
     * 创建指定长度的数组并填充
     *
     * @param length 长度
     * @param value  填充值
     * @return 创建的数组
     */
    public static double[] newArray(int length, double value) {
        if (length <= 0) {
            return EMPTY_DOUBLE_ARRAY;
        }

        double[] array = new double[length];
        Arrays.fill(array, value);
        return array;
    }

    /**
     * 创建指定长度的数组并填充
     *
     * @param length 长度
     * @param value  填充值
     * @return 创建的数组
     */
    public static float[] newArray(int length, float value) {
        if (length <= 0) {
            return EMPTY_FLOAT_ARRAY;
        }

        float[] array = new float[length];
        Arrays.fill(array, value);
        return array;
    }

    /**
     * 创建指定长度的数组并填充
     *
     * @param length 长度
     * @param value  填充值
     * @return 创建的数组
     */
    public static int[] newArray(int length, int value) {
        if (length <= 0) {
            return EMPTY_INT_ARRAY;
        }

        int[] array = new int[length];
        Arrays.fill(array, value);
        return array;
    }

    /**
     * 创建指定长度的数组并填充
     *
     * @param length 长度
     * @param value  填充值
     * @return 创建的数组
     */
    public static long[] newArray(int length, long value) {
        if (length <= 0) {
            return EMPTY_LONG_ARRAY;
        }

        long[] array = new long[length];
        Arrays.fill(array, value);
        return array;
    }

    /**
     * 创建指定长度的数组并填充
     *
     * @param length 长度
     * @param value  填充值
     * @return 创建的数组
     */
    public static short[] newArray(int length, short value) {
        if (length <= 0) {
            return EMPTY_SHORT_ARRAY;
        }

        short[] array = new short[length];
        Arrays.fill(array, value);
        return array;
    }

    /**
     * 克隆数组
     *
     * <p>
     * 当 {@code array} 长度为 0 时，返回的是共享的空数组实例，
     * 而不是 {@code array} 的克隆。
     *
     * @param array 数组
     * @return 克隆后的数组，如果 {@code array} 为 {@code null} 则返回 {@code null}
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] clone(T[] array) {
        if (array == null) {
            return null;
        }
        return array.length == 0 ? (T[]) EMPTY_OBJECT_ARRAY : array.clone();
    }

    /**
     * 克隆数组
     *
     * <p>
     * 当 {@code array} 长度为 0 时，返回的是共享的空数组实例，
     * 而不是 {@code array} 的克隆。
     *
     * @param array 数组
     * @return 克隆后的数组，如果 {@code array} 为 {@code null} 则返回 {@code null}
     */
    public static boolean[] clone(boolean[] array) {
        if (array == null) {
            return null;
        }
        return array.length == 0 ? EMPTY_BOOLEAN_ARRAY : array.clone();
    }

    /**
     * 克隆数组
     *
     * <p>
     * 当 {@code array} 长度为 0 时，返回的是共享的空数组实例，
     * 而不是 {@code array} 的克隆。
     *
     * @param array 数组
     * @return 克隆后的数组，如果 {@code array} 为 {@code null} 则返回 {@code null}
     */
    public static byte[] clone(byte[] array) {
        if (array == null) {
            return null;
        }
        return array.length == 0 ? EMPTY_BYTE_ARRAY : array.clone();
    }

    /**
     * 克隆数组
     *
     * <p>
     * 当 {@code array} 长度为 0 时，返回的是共享的空数组实例，
     * 而不是 {@code array} 的克隆。
     *
     * @param array 数组
     * @return 克隆后的数组，如果 {@code array} 为 {@code null} 则返回 {@code null}
     */
    public static char[] clone(char[] array) {
        if (array == null) {
            return null;
        }
        return array.length == 0 ? EMPTY_CHAR_ARRAY : array.clone();
    }

    /**
     * 克隆数组
     *
     * <p>
     * 当 {@code array} 长度为 0 时，返回的是共享的空数组实例，
     * 而不是 {@code array} 的克隆。
     *
     * @param array 数组
     * @return 克隆后的数组，如果 {@code array} 为 {@code null} 则返回 {@code null}
     */
    public static double[] clone(double[] array) {
        if (array == null) {
            return null;
        }
        return array.length == 0 ? EMPTY_DOUBLE_ARRAY : array.clone();
    }

    /**
     * 克隆数组
     *
     * <p>
     * 当 {@code array} 长度为 0 时，返回的是共享的空数组实例，
     * 而不是 {@code array} 的克隆。
     *
     * @param array 数组
     * @return 克隆后的数组，如果 {@code array} 为 {@code null} 则返回 {@code null}
     */
    public static float[] clone(float[] array) {
        if (array == null) {
            return null;
        }
        return array.length == 0 ? EMPTY_FLOAT_ARRAY : array.clone();
    }

    /**
     * 克隆数组
     *
     * <p>
     * 当 {@code array} 长度为 0 时，返回的是共享的空数组实例，
     * 而不是 {@code array} 的克隆。
     *
     * @param array 数组
     * @return 克隆后的数组，如果 {@code array} 为 {@code null} 则返回 {@code null}
     */
    public static int[] clone(int[] array) {
        if (array == null) {
            return null;
        }
        return array.length == 0 ? EMPTY_INT_ARRAY : array.clone();
    }

    /**
     * 克隆数组
     *
     * <p>
     * 当 {@code array} 长度为 0 时，返回的是共享的空数组实例，
     * 而不是 {@code array} 的克隆。
     *
     * @param array 数组
     * @return 克隆后的数组，如果 {@code array} 为 {@code null} 则返回 {@code null}
     */
    public static long[] clone(long[] array) {
        if (array == null) {
            return null;
        }
        return array.length == 0 ? EMPTY_LONG_ARRAY : array.clone();
    }

    /**
     * 克隆数组
     *
     * <p>
     * 当 {@code array} 长度为 0 时，返回的是共享的空数组实例，
     * 而不是 {@code array} 的克隆。
     *
     * @param array 数组
     * @return 克隆后的数组，如果 {@code array} 为 {@code null} 则返回 {@code null}
     */
    public static short[] clone(short[] array) {
        if (array == null) {
            return null;
        }
        return array.length == 0 ? EMPTY_SHORT_ARRAY : array.clone();
    }

    /**
     * 向数组中添加元素
     *
     * <p>
     * 根据数组 {@code array} 或 {@code element} 的类型创建一个新数组，
     * 这两个参数不能同时为 {@code null}，否则无法获取数组元素类型。
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] add(T[] array, T element) {
        Class<?> type;
        if (array != null) {
            type = array.getClass().getComponentType();
        } else {
            Assert.notNull(element, "Array and element must not both be null");
            type = element.getClass();
        }

        T[] newArray = array == null ? (T[]) Array.newInstance(type, 1) : Arrays.copyOf(array, array.length + 1);
        newArray[newArray.length - 1] = element;
        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static boolean[] add(boolean[] array, boolean element) {
        boolean[] newArray = array == null ? new boolean[1] : Arrays.copyOf(array, array.length + 1);
        newArray[newArray.length - 1] = element;
        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static byte[] add(byte[] array, byte element) {
        byte[] newArray = array == null ? new byte[1] : Arrays.copyOf(array, array.length + 1);
        newArray[newArray.length - 1] = element;
        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static char[] add(char[] array, char element) {
        char[] newArray = array == null ? new char[1] : Arrays.copyOf(array, array.length + 1);
        newArray[newArray.length - 1] = element;
        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static double[] add(double[] array, double element) {
        double[] newArray = array == null ? new double[1] : Arrays.copyOf(array, array.length + 1);
        newArray[newArray.length - 1] = element;
        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static float[] add(float[] array, float element) {
        float[] newArray = array == null ? new float[1] : Arrays.copyOf(array, array.length + 1);
        newArray[newArray.length - 1] = element;
        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static int[] add(int[] array, int element) {
        int[] newArray = array == null ? new int[1] : Arrays.copyOf(array, array.length + 1);
        newArray[newArray.length - 1] = element;
        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static long[] add(long[] array, long element) {
        long[] newArray = array == null ? new long[1] : Arrays.copyOf(array, array.length + 1);
        newArray[newArray.length - 1] = element;
        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static short[] add(short[] array, short element) {
        short[] newArray = array == null ? new short[1] : Arrays.copyOf(array, array.length + 1);
        newArray[newArray.length - 1] = element;
        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array        数组
     * @param element      要添加的元素
     * @param moreElements 更多要添加的元素
     * @return 新数组
     */
    @SafeVarargs
    public static <T> T[] addAll(T[] array, T element, T... moreElements) {
        return addAll(array, addFirst(moreElements, element));
    }

    /**
     * 向数组中添加元素
     *
     * @param array    数组
     * @param elements 要添加的元素
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] addAll(T[] array, T[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 创建新数组
        Class<? extends T[]> type = (Class<? extends T[]>) array.getClass().getComponentType();
        try {
            T[] newArray = Arrays.copyOf(array, array.length + elements.length, type);
            System.arraycopy(elements, 0, newArray, array.length, elements.length);
            return newArray;
        } catch (ArrayStoreException e) {
            Class<?> elementType = elements.getClass().getComponentType();
            if (!type.isAssignableFrom(elementType)) {
                throw new IllegalArgumentException("Cannot store element of type" + elementType.getName() + " in an array of " + type.getName(), e);
            } else {
                throw e;
            }
        }
    }

    /**
     * 向数组中添加元素
     *
     * @param array        数组
     * @param element      要添加的元素
     * @param moreElements 更多要添加的元素
     * @return 新数组
     */
    public static boolean[] addAll(boolean[] array, boolean element, boolean... moreElements) {
        return addAll(array, addFirst(moreElements, element));
    }

    /**
     * 向数组中添加元素
     *
     * @param array    数组
     * @param elements 要添加的元素
     * @return 新数组
     */
    public static boolean[] addAll(boolean[] array, boolean[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 创建新数组
        boolean[] newArray = new boolean[array.length + elements.length];
        System.arraycopy(array, 0, newArray, 0, array.length);
        System.arraycopy(elements, 0, newArray, array.length, elements.length);

        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array        数组
     * @param element      要添加的元素
     * @param moreElements 更多要添加的元素
     * @return 新数组
     */
    public static byte[] addAll(byte[] array, byte element, byte... moreElements) {
        return addAll(array, addFirst(moreElements, element));
    }

    /**
     * 向数组中添加元素
     *
     * @param array    数组
     * @param elements 要添加的元素
     * @return 新数组
     */
    public static byte[] addAll(byte[] array, byte[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 创建新数组
        byte[] newArray = new byte[array.length + elements.length];
        System.arraycopy(array, 0, newArray, 0, array.length);
        System.arraycopy(elements, 0, newArray, array.length, elements.length);

        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array        数组
     * @param element      要添加的元素
     * @param moreElements 更多要添加的元素
     * @return 新数组
     */
    public static char[] addAll(char[] array, char element, char... moreElements) {
        return addAll(array, addFirst(moreElements, element));
    }

    /**
     * 向数组中添加元素
     *
     * @param array    数组
     * @param elements 要添加的元素
     * @return 新数组
     */
    public static char[] addAll(char[] array, char[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 创建新数组
        char[] newArray = new char[array.length + elements.length];
        System.arraycopy(array, 0, newArray, 0, array.length);
        System.arraycopy(elements, 0, newArray, array.length, elements.length);

        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array        数组
     * @param element      要添加的元素
     * @param moreElements 更多要添加的元素
     * @return 新数组
     */
    public static double[] addAll(double[] array, double element, double... moreElements) {
        return addAll(array, addFirst(moreElements, element));
    }

    /**
     * 向数组中添加元素
     *
     * @param array    数组
     * @param elements 要添加的元素
     * @return 新数组
     */
    public static double[] addAll(double[] array, double[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 创建新数组
        double[] newArray = new double[array.length + elements.length];
        System.arraycopy(array, 0, newArray, 0, array.length);
        System.arraycopy(elements, 0, newArray, array.length, elements.length);

        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array        数组
     * @param element      要添加的元素
     * @param moreElements 更多要添加的元素
     * @return 新数组
     */
    public static float[] addAll(float[] array, float element, float... moreElements) {
        return addAll(array, addFirst(moreElements, element));
    }

    /**
     * 向数组中添加元素
     *
     * @param array    数组
     * @param elements 要添加的元素
     * @return 新数组
     */
    public static float[] addAll(float[] array, float[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 创建新数组
        float[] newArray = new float[array.length + elements.length];
        System.arraycopy(array, 0, newArray, 0, array.length);
        System.arraycopy(elements, 0, newArray, array.length, elements.length);

        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array        数组
     * @param element      要添加的元素
     * @param moreElements 更多要添加的元素
     * @return 新数组
     */
    public static int[] addAll(int[] array, int element, int... moreElements) {
        return addAll(array, addFirst(moreElements, element));
    }

    /**
     * 向数组中添加元素
     *
     * @param array    数组
     * @param elements 要添加的元素
     * @return 新数组
     */
    public static int[] addAll(int[] array, int[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 创建新数组
        int[] newArray = new int[array.length + elements.length];
        System.arraycopy(array, 0, newArray, 0, array.length);
        System.arraycopy(elements, 0, newArray, array.length, elements.length);

        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array        数组
     * @param element      要添加的元素
     * @param moreElements 更多要添加的元素
     * @return 新数组
     */
    public static long[] addAll(long[] array, long element, long... moreElements) {
        return addAll(array, addFirst(moreElements, element));
    }

    /**
     * 向数组中添加元素
     *
     * @param array    数组
     * @param elements 要添加的元素
     * @return 新数组
     */
    public static long[] addAll(long[] array, long[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 创建新数组
        long[] newArray = new long[array.length + elements.length];
        System.arraycopy(array, 0, newArray, 0, array.length);
        System.arraycopy(elements, 0, newArray, array.length, elements.length);

        return newArray;
    }

    /**
     * 向数组中添加元素
     *
     * @param array        数组
     * @param element      要添加的元素
     * @param moreElements 更多要添加的元素
     * @return 新数组
     */
    public static short[] addAll(short[] array, short element, short... moreElements) {
        return addAll(array, addFirst(moreElements, element));
    }

    /**
     * 向数组中添加元素
     *
     * @param array    数组
     * @param elements 要添加的元素
     * @return 新数组
     */
    public static short[] addAll(short[] array, short[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 创建新数组
        short[] newArray = new short[array.length + elements.length];
        System.arraycopy(array, 0, newArray, 0, array.length);
        System.arraycopy(elements, 0, newArray, array.length, elements.length);

        return newArray;
    }

    /**
     * 向数组开头添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static <T> T[] addFirst(T[] array, T element) {
        return insert(array, 0, element);
    }

    /**
     * 向数组开头添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static boolean[] addFirst(boolean[] array, boolean element) {
        return insert(array, 0, element);
    }

    /**
     * 向数组开头添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static byte[] addFirst(byte[] array, byte element) {
        return insert(array, 0, element);
    }

    /**
     * 向数组开头添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static char[] addFirst(char[] array, char element) {
        return insert(array, 0, element);
    }

    /**
     * 向数组开头添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static double[] addFirst(double[] array, double element) {
        return insert(array, 0, element);
    }

    /**
     * 向数组开头添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static float[] addFirst(float[] array, float element) {
        return insert(array, 0, element);
    }

    /**
     * 向数组开头添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static int[] addFirst(int[] array, int element) {
        return insert(array, 0, element);
    }

    /**
     * 向数组开头添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static long[] addFirst(long[] array, long element) {
        return insert(array, 0, element);
    }

    /**
     * 向数组开头添加元素
     *
     * @param array   数组
     * @param element 要添加的元素
     * @return 新数组
     */
    public static short[] addFirst(short[] array, short element) {
        return insert(array, 0, element);
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array   数组
     * @param index   索引
     * @param element 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] insert(T[] array, int index, T element) {
        // 处理空数组
        if (isEmpty(array)) {
            return add(array, element);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length + 1);

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        newArray[index] = element;
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + 1, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array   数组
     * @param index   索引
     * @param element 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static boolean[] insert(boolean[] array, int index, boolean element) {
        // 处理空数组
        if (isEmpty(array)) {
            return add(array, element);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        boolean[] newArray = new boolean[array.length + 1];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        newArray[index] = element;
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + 1, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array   数组
     * @param index   索引
     * @param element 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static byte[] insert(byte[] array, int index, byte element) {
        // 处理空数组
        if (isEmpty(array)) {
            return add(array, element);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        byte[] newArray = new byte[array.length + 1];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        newArray[index] = element;
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + 1, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array   数组
     * @param index   索引
     * @param element 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static char[] insert(char[] array, int index, char element) {
        // 处理空数组
        if (isEmpty(array)) {
            return add(array, element);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        char[] newArray = new char[array.length + 1];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        newArray[index] = element;
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + 1, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array   数组
     * @param index   索引
     * @param element 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static double[] insert(double[] array, int index, double element) {
        // 处理空数组
        if (isEmpty(array)) {
            return add(array, element);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        double[] newArray = new double[array.length + 1];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        newArray[index] = element;
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + 1, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array   数组
     * @param index   索引
     * @param element 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static float[] insert(float[] array, int index, float element) {
        // 处理空数组
        if (isEmpty(array)) {
            return add(array, element);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        float[] newArray = new float[array.length + 1];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        newArray[index] = element;
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + 1, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array   数组
     * @param index   索引
     * @param element 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static int[] insert(int[] array, int index, int element) {
        // 处理空数组
        if (isEmpty(array)) {
            return add(array, element);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        int[] newArray = new int[array.length + 1];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        newArray[index] = element;
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + 1, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array   数组
     * @param index   索引
     * @param element 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static long[] insert(long[] array, int index, long element) {
        // 处理空数组
        if (isEmpty(array)) {
            return add(array, element);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        long[] newArray = new long[array.length + 1];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        newArray[index] = element;
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + 1, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array   数组
     * @param index   索引
     * @param element 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static short[] insert(short[] array, int index, short element) {
        // 处理空数组
        if (isEmpty(array)) {
            return add(array, element);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        short[] newArray = new short[array.length + 1];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        newArray[index] = element;
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + 1, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array        数组
     * @param index        索引
     * @param element      要插入的元素
     * @param moreElements 更多要插入的元素
     * @return 新数组
     */
    @SafeVarargs
    public static <T> T[] insertAll(T[] array, int index, T element, T... moreElements) {
        return insertAll(array, index, addFirst(moreElements, element));
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array    数组
     * @param index    索引
     * @param elements 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] insertAll(T[] array, int index, T[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length + elements.length);

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        System.arraycopy(elements, 0, newArray, index, elements.length);
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + elements.length, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array        数组
     * @param index        索引
     * @param element      要插入的元素
     * @param moreElements 更多要插入的元素
     * @return 新数组
     */
    public static boolean[] insertAll(boolean[] array, int index, boolean element, boolean... moreElements) {
        return insertAll(array, index, addFirst(moreElements, element));
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array    数组
     * @param index    索引
     * @param elements 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static boolean[] insertAll(boolean[] array, int index, boolean[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        boolean[] newArray = new boolean[array.length + elements.length];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        System.arraycopy(elements, 0, newArray, index, elements.length);
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + elements.length, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array        数组
     * @param index        索引
     * @param element      要插入的元素
     * @param moreElements 更多要插入的元素
     * @return 新数组
     */
    public static byte[] insertAll(byte[] array, int index, byte element, byte... moreElements) {
        return insertAll(array, index, addFirst(moreElements, element));
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array    数组
     * @param index    索引
     * @param elements 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static byte[] insertAll(byte[] array, int index, byte[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        byte[] newArray = new byte[array.length + elements.length];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        System.arraycopy(elements, 0, newArray, index, elements.length);
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + elements.length, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array        数组
     * @param index        索引
     * @param element      要插入的元素
     * @param moreElements 更多要插入的元素
     * @return 新数组
     */
    public static char[] insertAll(char[] array, int index, char element, char... moreElements) {
        return insertAll(array, index, addFirst(moreElements, element));
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array    数组
     * @param index    索引
     * @param elements 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static char[] insertAll(char[] array, int index, char[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        char[] newArray = new char[array.length + elements.length];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        System.arraycopy(elements, 0, newArray, index, elements.length);
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + elements.length, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array        数组
     * @param index        索引
     * @param element      要插入的元素
     * @param moreElements 更多要插入的元素
     * @return 新数组
     */
    public static double[] insertAll(double[] array, int index, double element, double... moreElements) {
        return insertAll(array, index, addFirst(moreElements, element));
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array    数组
     * @param index    索引
     * @param elements 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static double[] insertAll(double[] array, int index, double[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        double[] newArray = new double[array.length + elements.length];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        System.arraycopy(elements, 0, newArray, index, elements.length);
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + elements.length, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array        数组
     * @param index        索引
     * @param element      要插入的元素
     * @param moreElements 更多要插入的元素
     * @return 新数组
     */
    public static float[] insertAll(float[] array, int index, float element, float... moreElements) {
        return insertAll(array, index, addFirst(moreElements, element));
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array    数组
     * @param index    索引
     * @param elements 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static float[] insertAll(float[] array, int index, float[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        float[] newArray = new float[array.length + elements.length];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        System.arraycopy(elements, 0, newArray, index, elements.length);
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + elements.length, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array        数组
     * @param index        索引
     * @param element      要插入的元素
     * @param moreElements 更多要插入的元素
     * @return 新数组
     */
    public static int[] insertAll(int[] array, int index, int element, int... moreElements) {
        return insertAll(array, index, addFirst(moreElements, element));
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array    数组
     * @param index    索引
     * @param elements 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static int[] insertAll(int[] array, int index, int[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        int[] newArray = new int[array.length + elements.length];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        System.arraycopy(elements, 0, newArray, index, elements.length);
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + elements.length, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array        数组
     * @param index        索引
     * @param element      要插入的元素
     * @param moreElements 更多要插入的元素
     * @return 新数组
     */
    public static long[] insertAll(long[] array, int index, long element, long... moreElements) {
        return insertAll(array, index, addFirst(moreElements, element));
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array    数组
     * @param index    索引
     * @param elements 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static long[] insertAll(long[] array, int index, long[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        long[] newArray = new long[array.length + elements.length];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        System.arraycopy(elements, 0, newArray, index, elements.length);
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + elements.length, array.length - index);

        return newArray;
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array        数组
     * @param index        索引
     * @param element      要插入的元素
     * @param moreElements 更多要插入的元素
     * @return 新数组
     */
    public static short[] insertAll(short[] array, int index, short element, short... moreElements) {
        return insertAll(array, index, addFirst(moreElements, element));
    }

    /**
     * 在数组指定位置插入元素
     *
     * @param array    数组
     * @param index    索引
     * @param elements 要插入的元素
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static short[] insertAll(short[] array, int index, short[] elements) {
        // 处理空元素
        if (isEmpty(elements)) {
            return clone(array);
        }

        // 处理空数组
        if (isEmpty(array)) {
            return clone(elements);
        }

        // 检查索引
        checkInsertIndex(index, array.length);

        // 创建新数组
        short[] newArray = new short[array.length + elements.length];

        // 处理指定索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理要插入的元素
        System.arraycopy(elements, 0, newArray, index, elements.length);
        // 处理指定索引之后的元素
        System.arraycopy(array, index, newArray, index + elements.length, array.length - index);

        return newArray;
    }

    /**
     * 判断数组中是否包含指定元素
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return boolean
     */
    public static <T> boolean contains(T[] array, T element) {
        return indexOf(array, element) != -1;
    }

    /**
     * 判断数组中是否包含指定元素
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return boolean
     */
    public static boolean contains(boolean[] array, boolean element) {
        return indexOf(array, element) != -1;
    }

    /**
     * 判断数组中是否包含指定元素
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return boolean
     */
    public static boolean contains(byte[] array, byte element) {
        return indexOf(array, element) != -1;
    }

    /**
     * 判断数组中是否包含指定元素
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return boolean
     */
    public static boolean contains(char[] array, char element) {
        return indexOf(array, element) != -1;
    }

    /**
     * 判断数组中是否包含指定元素
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return boolean
     */
    public static boolean contains(double[] array, double element) {
        return indexOf(array, element) != -1;
    }

    /**
     * 判断数组中是否包含指定元素
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return boolean
     */
    public static boolean contains(float[] array, float element) {
        return indexOf(array, element) != -1;
    }

    /**
     * 判断数组中是否包含指定元素
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return boolean
     */
    public static boolean contains(int[] array, int element) {
        return indexOf(array, element) != -1;
    }

    /**
     * 判断数组中是否包含指定元素
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return boolean
     */
    public static boolean contains(long[] array, long element) {
        return indexOf(array, element) != -1;
    }

    /**
     * 判断数组中是否包含指定元素
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return boolean
     */
    public static boolean contains(short[] array, short element) {
        return indexOf(array, element) != -1;
    }

    /**
     * 统计指定元素在数组中出现的次数
     *
     * @param array   数组
     * @param element 要统计的元素
     * @return 元素在数组中的出现次数
     */
    public static <T> int count(T[] array, T element) {
        return count(array, value -> Objects.equals(value, element));
    }

    /**
     * 统计符合条件的元素在数组中出现的次数
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 元素在数组中的出现次数
     */
    public static <T> int count(T[] array, Predicate<T> predicate) {
        int count = 0;

        if (isNotEmpty(array)) {
            for (T value : array) {
                if (predicate.test(value)) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 统计指定元素在数组中出现的次数
     *
     * @param array   数组
     * @param element 要统计的元素
     * @return 元素在数组中的出现次数
     */
    public static int count(boolean[] array, boolean element) {
        return count(array, value -> value == element);
    }

    /**
     * 统计符合条件的元素在数组中出现的次数
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 元素在数组中的出现次数
     */
    public static int count(boolean[] array, BooleanPredicate predicate) {
        int count = 0;

        if (isNotEmpty(array)) {
            for (boolean value : array) {
                if (predicate.test(value)) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 统计指定元素在数组中出现的次数
     *
     * @param array   数组
     * @param element 要统计的元素
     * @return 元素在数组中的出现次数
     */
    public static int count(byte[] array, byte element) {
        return count(array, value -> value == element);
    }

    /**
     * 统计符合条件的元素在数组中出现的次数
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 元素在数组中的出现次数
     */
    public static int count(byte[] array, BytePredicate predicate) {
        int count = 0;

        if (isNotEmpty(array)) {
            for (byte value : array) {
                if (predicate.test(value)) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 统计指定元素在数组中出现的次数
     *
     * @param array   数组
     * @param element 要统计的元素
     * @return 元素在数组中的出现次数
     */
    public static int count(char[] array, char element) {
        return count(array, value -> value == element);
    }

    /**
     * 统计符合条件的元素在数组中出现的次数
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 元素在数组中的出现次数
     */
    public static int count(char[] array, CharPredicate predicate) {
        int count = 0;

        if (isNotEmpty(array)) {
            for (char value : array) {
                if (predicate.test(value)) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 统计指定元素在数组中出现的次数
     *
     * @param array   数组
     * @param element 要统计的元素
     * @return 元素在数组中的出现次数
     */
    public static int count(double[] array, double element) {
        return count(array, value -> value == element);
    }

    /**
     * 统计符合条件的元素在数组中出现的次数
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 元素在数组中的出现次数
     */
    public static int count(double[] array, DoublePredicate predicate) {
        int count = 0;

        if (isNotEmpty(array)) {
            for (double value : array) {
                if (predicate.test(value)) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 统计指定元素在数组中出现的次数
     *
     * @param array   数组
     * @param element 要统计的元素
     * @return 元素在数组中的出现次数
     */
    public static int count(float[] array, float element) {
        return count(array, value -> value == element);
    }

    /**
     * 统计符合条件的元素在数组中出现的次数
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 元素在数组中的出现次数
     */
    public static int count(float[] array, FloatPredicate predicate) {
        int count = 0;

        if (isNotEmpty(array)) {
            for (float value : array) {
                if (predicate.test(value)) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 统计指定元素在数组中出现的次数
     *
     * @param array   数组
     * @param element 要统计的元素
     * @return 元素在数组中的出现次数
     */
    public static int count(int[] array, int element) {
        return count(array, value -> value == element);
    }

    /**
     * 统计符合条件的元素在数组中出现的次数
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 元素在数组中的出现次数
     */
    public static int count(int[] array, IntPredicate predicate) {
        int count = 0;

        if (isNotEmpty(array)) {
            for (int value : array) {
                if (predicate.test(value)) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 统计指定元素在数组中出现的次数
     *
     * @param array   数组
     * @param element 要统计的元素
     * @return 元素在数组中的出现次数
     */
    public static int count(long[] array, long element) {
        return count(array, value -> value == element);
    }

    /**
     * 统计符合条件的元素在数组中出现的次数
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 元素在数组中的出现次数
     */
    public static int count(long[] array, LongPredicate predicate) {
        int count = 0;

        if (isNotEmpty(array)) {
            for (long value : array) {
                if (predicate.test(value)) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 统计指定元素在数组中出现的次数
     *
     * @param array   数组
     * @param element 要统计的元素
     * @return 元素在数组中的出现次数
     */
    public static int count(short[] array, short element) {
        return count(array, value -> value == element);
    }

    /**
     * 统计符合条件的元素在数组中出现的次数
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 元素在数组中的出现次数
     */
    public static int count(short[] array, ShortPredicate predicate) {
        int count = 0;

        if (isNotEmpty(array)) {
            for (short value : array) {
                if (predicate.test(value)) {
                    count++;
                }
            }
        }

        return count;
    }

    /**
     * 获取元素首次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static <T> int indexOf(T[] array, T element) {
        return indexOf(array, element, 0);
    }

    /**
     * 获取元素首次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组末尾方向查找(正向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则返回 {@code -1}，
     * 如果 {@code fromIndex} 小于 {@code 0}，则从数组开头开始查找
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static <T> int indexOf(T[] array, T element, int fromIndex) {
        if (isEmpty(array) || fromIndex >= array.length) {
            return -1;
        }

        if (fromIndex < 0) {
            fromIndex = 0;
        }

        for (int i = fromIndex; i < array.length; i++) {
            if ((element == null && array[i] == null) || (element != null && element.equals(array[i]))) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素首次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(boolean[] array, boolean element) {
        return indexOf(array, element, 0);
    }

    /**
     * 获取元素首次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组末尾方向查找(正向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则返回 {@code -1}，
     * 如果 {@code fromIndex} 小于 {@code 0}，则从数组开头开始查找
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(boolean[] array, boolean element, int fromIndex) {
        if (isEmpty(array) || fromIndex >= array.length) {
            return -1;
        }

        if (fromIndex < 0) {
            fromIndex = 0;
        }

        for (int i = fromIndex; i < array.length; i++) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素首次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(byte[] array, byte element) {
        return indexOf(array, element, 0);
    }

    /**
     * 获取元素首次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组末尾方向查找(正向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则返回 {@code -1}，
     * 如果 {@code fromIndex} 小于 {@code 0}，则从数组开头开始查找
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(byte[] array, byte element, int fromIndex) {
        if (isEmpty(array) || fromIndex >= array.length) {
            return -1;
        }

        if (fromIndex < 0) {
            fromIndex = 0;
        }

        for (int i = fromIndex; i < array.length; i++) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素首次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(char[] array, char element) {
        return indexOf(array, element, 0);
    }

    /**
     * 获取元素首次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组末尾方向查找(正向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则返回 {@code -1}，
     * 如果 {@code fromIndex} 小于 {@code 0}，则从数组开头开始查找
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(char[] array, char element, int fromIndex) {
        if (isEmpty(array) || fromIndex >= array.length) {
            return -1;
        }

        if (fromIndex < 0) {
            fromIndex = 0;
        }

        for (int i = fromIndex; i < array.length; i++) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素首次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(double[] array, double element) {
        return indexOf(array, element, 0);
    }

    /**
     * 获取元素首次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组末尾方向查找(正向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则返回 {@code -1}，
     * 如果 {@code fromIndex} 小于 {@code 0}，则从数组开头开始查找
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(double[] array, double element, int fromIndex) {
        if (isEmpty(array) || fromIndex >= array.length) {
            return -1;
        }

        if (fromIndex < 0) {
            fromIndex = 0;
        }

        for (int i = fromIndex; i < array.length; i++) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素首次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(float[] array, float element) {
        return indexOf(array, element, 0);
    }

    /**
     * 获取元素首次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组末尾方向查找(正向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则返回 {@code -1}，
     * 如果 {@code fromIndex} 小于 {@code 0}，则从数组开头开始查找
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(float[] array, float element, int fromIndex) {
        if (isEmpty(array) || fromIndex >= array.length) {
            return -1;
        }

        if (fromIndex < 0) {
            fromIndex = 0;
        }

        for (int i = fromIndex; i < array.length; i++) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素首次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(int[] array, int element) {
        return indexOf(array, element, 0);
    }

    /**
     * 获取元素首次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组末尾方向查找(正向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则返回 {@code -1}，
     * 如果 {@code fromIndex} 小于 {@code 0}，则从数组开头开始查找
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(int[] array, int element, int fromIndex) {
        if (isEmpty(array) || fromIndex >= array.length) {
            return -1;
        }

        if (fromIndex < 0) {
            fromIndex = 0;
        }

        for (int i = fromIndex; i < array.length; i++) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素首次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(long[] array, long element) {
        return indexOf(array, element, 0);
    }

    /**
     * 获取元素首次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组末尾方向查找(正向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则返回 {@code -1}，
     * 如果 {@code fromIndex} 小于 {@code 0}，则从数组开头开始查找
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(long[] array, long element, int fromIndex) {
        if (isEmpty(array) || fromIndex >= array.length) {
            return -1;
        }

        if (fromIndex < 0) {
            fromIndex = 0;
        }

        for (int i = fromIndex; i < array.length; i++) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素首次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(short[] array, short element) {
        return indexOf(array, element, 0);
    }

    /**
     * 获取元素首次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组末尾方向查找(正向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则返回 {@code -1}，
     * 如果 {@code fromIndex} 小于 {@code 0}，则从数组开头开始查找
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int indexOf(short[] array, short element, int fromIndex) {
        if (isEmpty(array) || fromIndex >= array.length) {
            return -1;
        }

        if (fromIndex < 0) {
            fromIndex = 0;
        }

        for (int i = fromIndex; i < array.length; i++) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static <T> int lastIndexOf(T[] array, T element) {
        return lastIndexOf(array, element, Integer.MAX_VALUE);
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组开头方向查找(反向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则从数组末尾开始查找，
     * 如果 {@code fromIndex} 小于 {@code 0}，则返回 {@code -1}
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static <T> int lastIndexOf(T[] array, T element, int fromIndex) {
        if (fromIndex < 0 || isEmpty(array)) {
            return -1;
        }

        if (fromIndex >= array.length) {
            fromIndex = array.length - 1;
        }

        for (int i = fromIndex; i >= 0; i--) {
            if ((element == null && array[i] == null) || (element != null && element.equals(array[i]))) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(boolean[] array, boolean element) {
        return lastIndexOf(array, element, Integer.MAX_VALUE);
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组开头方向查找(反向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则从数组末尾开始查找，
     * 如果 {@code fromIndex} 小于 {@code 0}，则返回 {@code -1}
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(boolean[] array, boolean element, int fromIndex) {
        if (fromIndex < 0 || isEmpty(array)) {
            return -1;
        }

        if (fromIndex >= array.length) {
            fromIndex = array.length - 1;
        }

        for (int i = fromIndex; i >= 0; i--) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(byte[] array, byte element) {
        return lastIndexOf(array, element, Integer.MAX_VALUE);
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组开头方向查找(反向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则从数组末尾开始查找，
     * 如果 {@code fromIndex} 小于 {@code 0}，则返回 {@code -1}
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(byte[] array, byte element, int fromIndex) {
        if (fromIndex < 0 || isEmpty(array)) {
            return -1;
        }

        if (fromIndex >= array.length) {
            fromIndex = array.length - 1;
        }

        for (int i = fromIndex; i >= 0; i--) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(char[] array, char element) {
        return lastIndexOf(array, element, Integer.MAX_VALUE);
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组开头方向查找(反向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则从数组末尾开始查找，
     * 如果 {@code fromIndex} 小于 {@code 0}，则返回 {@code -1}
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(char[] array, char element, int fromIndex) {
        if (fromIndex < 0 || isEmpty(array)) {
            return -1;
        }

        if (fromIndex >= array.length) {
            fromIndex = array.length - 1;
        }

        for (int i = fromIndex; i >= 0; i--) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(double[] array, double element) {
        return lastIndexOf(array, element, Integer.MAX_VALUE);
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组开头方向查找(反向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则从数组末尾开始查找，
     * 如果 {@code fromIndex} 小于 {@code 0}，则返回 {@code -1}
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(double[] array, double element, int fromIndex) {
        if (fromIndex < 0 || isEmpty(array)) {
            return -1;
        }

        if (fromIndex >= array.length) {
            fromIndex = array.length - 1;
        }

        for (int i = fromIndex; i >= 0; i--) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(float[] array, float element) {
        return lastIndexOf(array, element, Integer.MAX_VALUE);
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组开头方向查找(反向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则从数组末尾开始查找，
     * 如果 {@code fromIndex} 小于 {@code 0}，则返回 {@code -1}
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(float[] array, float element, int fromIndex) {
        if (fromIndex < 0 || isEmpty(array)) {
            return -1;
        }

        if (fromIndex >= array.length) {
            fromIndex = array.length - 1;
        }

        for (int i = fromIndex; i >= 0; i--) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(int[] array, int element) {
        return lastIndexOf(array, element, Integer.MAX_VALUE);
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组开头方向查找(反向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则从数组末尾开始查找，
     * 如果 {@code fromIndex} 小于 {@code 0}，则返回 {@code -1}
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(int[] array, int element, int fromIndex) {
        if (fromIndex < 0 || isEmpty(array)) {
            return -1;
        }

        if (fromIndex >= array.length) {
            fromIndex = array.length - 1;
        }

        for (int i = fromIndex; i >= 0; i--) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(long[] array, long element) {
        return lastIndexOf(array, element, Integer.MAX_VALUE);
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组开头方向查找(反向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则从数组末尾开始查找，
     * 如果 {@code fromIndex} 小于 {@code 0}，则返回 {@code -1}
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(long[] array, long element, int fromIndex) {
        if (fromIndex < 0 || isEmpty(array)) {
            return -1;
        }

        if (fromIndex >= array.length) {
            fromIndex = array.length - 1;
        }

        for (int i = fromIndex; i >= 0; i--) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * @param array   数组
     * @param element 要查找的元素
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(short[] array, short element) {
        return lastIndexOf(array, element, Integer.MAX_VALUE);
    }

    /**
     * 获取元素最后一次出现处的索引
     *
     * <p>
     * 从 {@code fromIndex} 开始向数组开头方向查找(反向查找)，
     * 如果 {@code fromIndex} 超出数组长度，则从数组末尾开始查找，
     * 如果 {@code fromIndex} 小于 {@code 0}，则返回 {@code -1}
     *
     * @param array     数组
     * @param element   要查找的元素
     * @param fromIndex 起始位置索引
     * @return 索引，未找到返回 {@code -1}
     */
    public static int lastIndexOf(short[] array, short element, int fromIndex) {
        if (fromIndex < 0 || isEmpty(array)) {
            return -1;
        }

        if (fromIndex >= array.length) {
            fromIndex = array.length - 1;
        }

        for (int i = fromIndex; i >= 0; i--) {
            if (element == array[i]) {
                return i;
            }
        }

        return -1;
    }

    /**
     * 判断数组是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isEmpty(Object[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 判断数组是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isEmpty(boolean[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 判断数组是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isEmpty(byte[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 判断数组是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isEmpty(char[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 判断数组是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isEmpty(double[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 判断数组是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isEmpty(float[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 判断数组是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isEmpty(int[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 判断数组是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isEmpty(long[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 判断数组是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isEmpty(short[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 判断数组是否不为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isNotEmpty(Object[] array) {
        return !isEmpty(array);
    }

    /**
     * 判断数组是否不为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isNotEmpty(boolean[] array) {
        return !isEmpty(array);
    }

    /**
     * 判断数组是否不为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isNotEmpty(byte[] array) {
        return !isEmpty(array);
    }

    /**
     * 判断数组是否不为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isNotEmpty(char[] array) {
        return !isEmpty(array);
    }

    /**
     * 判断数组是否不为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isNotEmpty(double[] array) {
        return !isEmpty(array);
    }

    /**
     * 判断数组是否不为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isNotEmpty(float[] array) {
        return !isEmpty(array);
    }

    /**
     * 判断数组是否不为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isNotEmpty(int[] array) {
        return !isEmpty(array);
    }

    /**
     * 判断数组是否不为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isNotEmpty(long[] array) {
        return !isEmpty(array);
    }

    /**
     * 判断数组是否不为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isNotEmpty(short[] array) {
        return !isEmpty(array);
    }

    /**
     * 判断数组中是否任意元素为 {@code null}
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isAnyNull(Object[] array) {
        if (isEmpty(array)) {
            return false;
        }

        for (Object o : array) {
            if (o == null) {
                return true;
            }
        }

        return false;
    }

    /**
     * 判断数组中是否任意元素不为 {@code null}
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isAnyNotNull(Object[] array) {
        if (isEmpty(array)) {
            return false;
        }

        for (Object o : array) {
            if (o != null) {
                return true;
            }
        }

        return false;
    }

    /**
     * 判断数组中是否所有元素均为 {@code null}
     *
     * <p>
     * 空数组将被视为 {@code true}，这是基于逻辑学中的 Vacuous Truth（空真）原则，
     * 当数组中没有元素时，所有元素满足某一条件的命题在逻辑上被认为为真。
     * 参考 <a href="https://en.wikipedia.org/wiki/Vacuous_truth">Vacuous Truth</a>
     * 中的 {@code In computer programming} 章节。
     * <p>
     * 此行为与主流工具库（如 Apache Commons 等）保持一致
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isAllNull(Object[] array) {
        return !isAnyNotNull(array);
    }

    /**
     * 判断数组中是否所有元素均不为 {@code null}
     *
     * <p>
     * 空数组将被视为 {@code true}，这是基于逻辑学中的 Vacuous Truth（空真）原则，
     * 当数组中没有元素时，所有元素满足某一条件的命题在逻辑上被认为为真。
     * 参考 <a href="https://en.wikipedia.org/wiki/Vacuous_truth">Vacuous Truth</a>
     * 中的 {@code In computer programming} 章节。
     * <p>
     * 此行为与主流工具库（如 Apache Commons 等）保持一致
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isAllNotNull(Object[] array) {
        return !isAnyNull(array);
    }

    /**
     * 判断数组中是否任意元素为空
     *
     * <p>
     * 使用 {@link ObjectUtil#isEmpty(Object)} 判断是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isAnyEmpty(Object[] array) {
        if (isEmpty(array)) {
            return false;
        }

        for (Object o : array) {
            if (ObjectUtil.isEmpty(o)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 判断数组中是否任意元素不为空
     *
     * <p>
     * 使用 {@link ObjectUtil#isEmpty(Object)} 判断是否为空
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isAnyNotEmpty(Object[] array) {
        if (isEmpty(array)) {
            return false;
        }

        for (Object o : array) {
            if (ObjectUtil.isNotEmpty(o)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 判断数组中是否所有元素均为空
     *
     * <p>
     * 使用 {@link ObjectUtil#isEmpty(Object)} 判断是否为空
     *
     * <p>
     * 空数组将被视为 {@code true}，这是基于逻辑学中的 Vacuous Truth（空真）原则，
     * 当数组中没有元素时，所有元素满足某一条件的命题在逻辑上被认为为真。
     * 参考 <a href="https://en.wikipedia.org/wiki/Vacuous_truth">Vacuous Truth</a>
     * 中的 {@code In computer programming} 章节。
     * <p>
     * 此行为与主流工具库（如 Apache Commons 等）保持一致
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isAllEmpty(Object[] array) {
        return !isAnyNotEmpty(array);
    }

    /**
     * 判断数组中是否所有元素均不为空
     *
     * <p>
     * 使用 {@link ObjectUtil#isEmpty(Object)} 判断是否为空
     *
     * <p>
     * 空数组将被视为 {@code true}，这是基于逻辑学中的 Vacuous Truth（空真）原则，
     * 当数组中没有元素时，所有元素满足某一条件的命题在逻辑上被认为为真。
     * 参考 <a href="https://en.wikipedia.org/wiki/Vacuous_truth">Vacuous Truth</a>
     * 中的 {@code In computer programming} 章节。
     * <p>
     * 此行为与主流工具库（如 Apache Commons 等）保持一致
     *
     * @param array 数组
     * @return boolean
     */
    public static boolean isAllNotEmpty(Object[] array) {
        return !isAnyEmpty(array);
    }

    /**
     * 判断数组长度是否相同
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return boolean
     */
    public static boolean isSameLength(Object[] array1, Object[] array2) {
        return getLength(array1) == getLength(array2);
    }

    /**
     * 判断数组长度是否相同
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return boolean
     */
    public static boolean isSameLength(boolean[] array1, boolean[] array2) {
        return getLength(array1) == getLength(array2);
    }

    /**
     * 判断数组长度是否相同
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return boolean
     */
    public static boolean isSameLength(byte[] array1, byte[] array2) {
        return getLength(array1) == getLength(array2);
    }

    /**
     * 判断数组长度是否相同
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return boolean
     */
    public static boolean isSameLength(char[] array1, char[] array2) {
        return getLength(array1) == getLength(array2);
    }

    /**
     * 判断数组长度是否相同
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return boolean
     */
    public static boolean isSameLength(double[] array1, double[] array2) {
        return getLength(array1) == getLength(array2);
    }

    /**
     * 判断数组长度是否相同
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return boolean
     */
    public static boolean isSameLength(float[] array1, float[] array2) {
        return getLength(array1) == getLength(array2);
    }

    /**
     * 判断数组长度是否相同
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return boolean
     */
    public static boolean isSameLength(int[] array1, int[] array2) {
        return getLength(array1) == getLength(array2);
    }

    /**
     * 判断数组长度是否相同
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return boolean
     */
    public static boolean isSameLength(long[] array1, long[] array2) {
        return getLength(array1) == getLength(array2);
    }

    /**
     * 判断数组长度是否相同
     *
     * @param array1 数组1
     * @param array2 数组2
     * @return boolean
     */
    public static boolean isSameLength(short[] array1, short[] array2) {
        return getLength(array1) == getLength(array2);
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array         数组
     * @param componentType 数组元素类型
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] emptyIfNull(T[] array, Class<T> componentType) {
        Assert.notNull(componentType, "Component type must not be null");
        return array == null ? (T[]) Array.newInstance(componentType, 0) : array;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static Object[] emptyIfNull(Object[] array) {
        return array != null ? array : EMPTY_OBJECT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static boolean[] emptyIfNull(boolean[] array) {
        return array != null ? array : EMPTY_BOOLEAN_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static Boolean[] emptyIfNull(Boolean[] array) {
        return array != null ? array : EMPTY_BOOLEAN_OBJECT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static byte[] emptyIfNull(byte[] array) {
        return array != null ? array : EMPTY_BYTE_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static Byte[] emptyIfNull(Byte[] array) {
        return array != null ? array : EMPTY_BYTE_OBJECT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static char[] emptyIfNull(char[] array) {
        return array != null ? array : EMPTY_CHAR_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static Character[] emptyIfNull(Character[] array) {
        return array != null ? array : EMPTY_CHARACTER_OBJECT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static double[] emptyIfNull(double[] array) {
        return array != null ? array : EMPTY_DOUBLE_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static Double[] emptyIfNull(Double[] array) {
        return array != null ? array : EMPTY_DOUBLE_OBJECT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static float[] emptyIfNull(float[] array) {
        return array != null ? array : EMPTY_FLOAT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static Float[] emptyIfNull(Float[] array) {
        return array != null ? array : EMPTY_FLOAT_OBJECT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static int[] emptyIfNull(int[] array) {
        return array != null ? array : EMPTY_INT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static Integer[] emptyIfNull(Integer[] array) {
        return array != null ? array : EMPTY_INTEGER_OBJECT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static long[] emptyIfNull(long[] array) {
        return array != null ? array : EMPTY_LONG_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static Long[] emptyIfNull(Long[] array) {
        return array != null ? array : EMPTY_LONG_OBJECT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static short[] emptyIfNull(short[] array) {
        return array != null ? array : EMPTY_SHORT_ARRAY;
    }

    /**
     * 返回原数组，或在为 {@code null} 时返回空数组
     *
     * @param array 数组
     * @return 如果 {@code array} 为 {@code null} 返回空数组，否则返回原数组
     */
    public static Short[] emptyIfNull(Short[] array) {
        return array != null ? array : EMPTY_SHORT_OBJECT_ARRAY;
    }

    /**
     * 移除数组指定位置的元素
     *
     * @param array 数组
     * @param index 索引
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] removeAt(T[] array, int index) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 检查索引
        Objects.checkIndex(index, array.length);

        // 创建新数组
        T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length - 1);
        // 处理索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理索引之后的元素
        System.arraycopy(array, index + 1, newArray, index, array.length - index - 1);

        return newArray;
    }

    /**
     * 移除数组指定位置的元素
     *
     * @param array 数组
     * @param index 索引
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static boolean[] removeAt(boolean[] array, int index) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 检查索引
        Objects.checkIndex(index, array.length);

        // 创建新数组
        boolean[] newArray = new boolean[array.length - 1];
        // 处理索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理索引之后的元素
        System.arraycopy(array, index + 1, newArray, index, array.length - index - 1);

        return newArray;
    }

    /**
     * 移除数组指定位置的元素
     *
     * @param array 数组
     * @param index 索引
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static byte[] removeAt(byte[] array, int index) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 检查索引
        Objects.checkIndex(index, array.length);

        // 创建新数组
        byte[] newArray = new byte[array.length - 1];
        // 处理索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理索引之后的元素
        System.arraycopy(array, index + 1, newArray, index, array.length - index - 1);

        return newArray;
    }

    /**
     * 移除数组指定位置的元素
     *
     * @param array 数组
     * @param index 索引
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static char[] removeAt(char[] array, int index) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 检查索引
        Objects.checkIndex(index, array.length);

        // 创建新数组
        char[] newArray = new char[array.length - 1];
        // 处理索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理索引之后的元素
        System.arraycopy(array, index + 1, newArray, index, array.length - index - 1);

        return newArray;
    }

    /**
     * 移除数组指定位置的元素
     *
     * @param array 数组
     * @param index 索引
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static double[] removeAt(double[] array, int index) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 检查索引
        Objects.checkIndex(index, array.length);

        // 创建新数组
        double[] newArray = new double[array.length - 1];
        // 处理索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理索引之后的元素
        System.arraycopy(array, index + 1, newArray, index, array.length - index - 1);

        return newArray;
    }

    /**
     * 移除数组指定位置的元素
     *
     * @param array 数组
     * @param index 索引
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static float[] removeAt(float[] array, int index) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 检查索引
        Objects.checkIndex(index, array.length);

        // 创建新数组
        float[] newArray = new float[array.length - 1];
        // 处理索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理索引之后的元素
        System.arraycopy(array, index + 1, newArray, index, array.length - index - 1);

        return newArray;
    }

    /**
     * 移除数组指定位置的元素
     *
     * @param array 数组
     * @param index 索引
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static int[] removeAt(int[] array, int index) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 检查索引
        Objects.checkIndex(index, array.length);

        // 创建新数组
        int[] newArray = new int[array.length - 1];
        // 处理索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理索引之后的元素
        System.arraycopy(array, index + 1, newArray, index, array.length - index - 1);

        return newArray;
    }

    /**
     * 移除数组指定位置的元素
     *
     * @param array 数组
     * @param index 索引
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static long[] removeAt(long[] array, int index) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 检查索引
        Objects.checkIndex(index, array.length);

        // 创建新数组
        long[] newArray = new long[array.length - 1];
        // 处理索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理索引之后的元素
        System.arraycopy(array, index + 1, newArray, index, array.length - index - 1);

        return newArray;
    }

    /**
     * 移除数组指定位置的元素
     *
     * @param array 数组
     * @param index 索引
     * @return 新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static short[] removeAt(short[] array, int index) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 检查索引
        Objects.checkIndex(index, array.length);

        // 创建新数组
        short[] newArray = new short[array.length - 1];
        // 处理索引之前的元素
        System.arraycopy(array, 0, newArray, 0, index);
        // 处理索引之后的元素
        System.arraycopy(array, index + 1, newArray, index, array.length - index - 1);

        return newArray;
    }

    /**
     * 从数组中移除第一个指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static <T> T[] removeFirst(T[] array, T element) {
        return removeFirst(array, value -> Objects.equals(value, element));
    }

    /**
     * 从数组中移除第一个符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static <T> T[] removeFirst(T[] array, Predicate<T> predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 查找元素首次出现的索引
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) {
                index = i;
                break;
            }
        }

        // 没有找到元素
        if (index == -1) {
            return clone(array);
        }

        // 通过索引移除元素
        return removeAt(array, index);
    }

    /**
     * 从数组中移除第一个指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static boolean[] removeFirst(boolean[] array, boolean element) {
        return removeFirst(array, value -> value == element);
    }

    /**
     * 从数组中移除第一个符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static boolean[] removeFirst(boolean[] array, BooleanPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 查找元素首次出现的索引
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) {
                index = i;
                break;
            }
        }

        // 没有找到元素
        if (index == -1) {
            return clone(array);
        }

        // 通过索引移除元素
        return removeAt(array, index);
    }

    /**
     * 从数组中移除第一个指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static byte[] removeFirst(byte[] array, byte element) {
        return removeFirst(array, value -> value == element);
    }

    /**
     * 从数组中移除第一个符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static byte[] removeFirst(byte[] array, BytePredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 查找元素首次出现的索引
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) {
                index = i;
                break;
            }
        }

        // 没有找到元素
        if (index == -1) {
            return clone(array);
        }

        // 通过索引移除元素
        return removeAt(array, index);
    }

    /**
     * 从数组中移除第一个指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static char[] removeFirst(char[] array, char element) {
        return removeFirst(array, value -> value == element);
    }

    /**
     * 从数组中移除第一个符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static char[] removeFirst(char[] array, CharPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 查找元素首次出现的索引
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) {
                index = i;
                break;
            }
        }

        // 没有找到元素
        if (index == -1) {
            return clone(array);
        }

        // 通过索引移除元素
        return removeAt(array, index);
    }

    /**
     * 从数组中移除第一个指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static double[] removeFirst(double[] array, double element) {
        return removeFirst(array, value -> value == element);
    }

    /**
     * 从数组中移除第一个符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static double[] removeFirst(double[] array, DoublePredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 查找元素首次出现的索引
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) {
                index = i;
                break;
            }
        }

        // 没有找到元素
        if (index == -1) {
            return clone(array);
        }

        // 通过索引移除元素
        return removeAt(array, index);
    }

    /**
     * 从数组中移除第一个指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static float[] removeFirst(float[] array, float element) {
        return removeFirst(array, value -> value == element);
    }

    /**
     * 从数组中移除第一个符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static float[] removeFirst(float[] array, FloatPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 查找元素首次出现的索引
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) {
                index = i;
                break;
            }
        }

        // 没有找到元素
        if (index == -1) {
            return clone(array);
        }

        // 通过索引移除元素
        return removeAt(array, index);
    }

    /**
     * 从数组中移除第一个指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static int[] removeFirst(int[] array, int element) {
        return removeFirst(array, value -> value == element);
    }

    /**
     * 从数组中移除第一个符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static int[] removeFirst(int[] array, IntPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 查找元素首次出现的索引
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) {
                index = i;
                break;
            }
        }

        // 没有找到元素
        if (index == -1) {
            return clone(array);
        }

        // 通过索引移除元素
        return removeAt(array, index);
    }

    /**
     * 从数组中移除第一个指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static long[] removeFirst(long[] array, long element) {
        return removeFirst(array, value -> value == element);
    }

    /**
     * 从数组中移除第一个符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static long[] removeFirst(long[] array, LongPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 查找元素首次出现的索引
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) {
                index = i;
                break;
            }
        }

        // 没有找到元素
        if (index == -1) {
            return clone(array);
        }

        // 通过索引移除元素
        return removeAt(array, index);
    }

    /**
     * 从数组中移除第一个指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static short[] removeFirst(short[] array, short element) {
        return removeFirst(array, value -> value == element);
    }

    /**
     * 从数组中移除第一个符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static short[] removeFirst(short[] array, ShortPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 查找元素首次出现的索引
        int index = -1;
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) {
                index = i;
                break;
            }
        }

        // 没有找到元素
        if (index == -1) {
            return clone(array);
        }

        // 通过索引移除元素
        return removeAt(array, index);
    }

    /**
     * 从数组中移除所有指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static <T> T[] removeAll(T[] array, T element) {
        return removeAll(array, value -> Objects.equals(value, element));
    }

    /**
     * 移除数组中所有符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] removeAll(T[] array, Predicate<T> predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 统计不等于目标元素的个数
        int count = 0;
        for (T value : array) {
            if (!predicate.test(value)) {
                count++;
            }
        }

        // 没有要移除的元素
        if (count == array.length) {
            return clone(array);
        }

        // 创建新数组
        T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), count);
        int index = 0;
        for (T value : array) {
            if (!predicate.test(value)) {
                newArray[index++] = value;
            }
        }

        return newArray;
    }

    /**
     * 从数组中移除所有指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static boolean[] removeAll(boolean[] array, boolean element) {
        return removeAll(array, value -> value == element);
    }

    /**
     * 移除数组中所有符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static boolean[] removeAll(boolean[] array, BooleanPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 统计不等于目标元素的个数
        int count = 0;
        for (boolean value : array) {
            if (!predicate.test(value)) {
                count++;
            }
        }

        // 没有要移除的元素
        if (count == array.length) {
            return clone(array);
        }

        // 创建新数组
        boolean[] newArray = new boolean[count];
        int index = 0;
        for (boolean value : array) {
            if (!predicate.test(value)) {
                newArray[index++] = value;
            }
        }

        return newArray;
    }

    /**
     * 从数组中移除所有指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static byte[] removeAll(byte[] array, byte element) {
        return removeAll(array, value -> value == element);
    }

    /**
     * 移除数组中所有符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static byte[] removeAll(byte[] array, BytePredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 统计不等于目标元素的个数
        int count = 0;
        for (byte value : array) {
            if (!predicate.test(value)) {
                count++;
            }
        }

        // 没有要移除的元素
        if (count == array.length) {
            return clone(array);
        }

        // 创建新数组
        byte[] newArray = new byte[count];
        int index = 0;
        for (byte value : array) {
            if (!predicate.test(value)) {
                newArray[index++] = value;
            }
        }

        return newArray;
    }

    /**
     * 从数组中移除所有指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static char[] removeAll(char[] array, char element) {
        return removeAll(array, value -> value == element);
    }

    /**
     * 移除数组中所有符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static char[] removeAll(char[] array, CharPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 统计不等于目标元素的个数
        int count = 0;
        for (char value : array) {
            if (!predicate.test(value)) {
                count++;
            }
        }

        // 没有要移除的元素
        if (count == array.length) {
            return clone(array);
        }

        // 创建新数组
        char[] newArray = new char[count];
        int index = 0;
        for (char value : array) {
            if (!predicate.test(value)) {
                newArray[index++] = value;
            }
        }

        return newArray;
    }

    /**
     * 从数组中移除所有指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static double[] removeAll(double[] array, double element) {
        return removeAll(array, value -> value == element);
    }

    /**
     * 移除数组中所有符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static double[] removeAll(double[] array, DoublePredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 统计不等于目标元素的个数
        int count = 0;
        for (double value : array) {
            if (!predicate.test(value)) {
                count++;
            }
        }

        // 没有要移除的元素
        if (count == array.length) {
            return clone(array);
        }

        // 创建新数组
        double[] newArray = new double[count];
        int index = 0;
        for (double value : array) {
            if (!predicate.test(value)) {
                newArray[index++] = value;
            }
        }

        return newArray;
    }

    /**
     * 从数组中移除所有指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static float[] removeAll(float[] array, float element) {
        return removeAll(array, value -> value == element);
    }

    /**
     * 移除数组中所有符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static float[] removeAll(float[] array, FloatPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 统计不等于目标元素的个数
        int count = 0;
        for (float value : array) {
            if (!predicate.test(value)) {
                count++;
            }
        }

        // 没有要移除的元素
        if (count == array.length) {
            return clone(array);
        }

        // 创建新数组
        float[] newArray = new float[count];
        int index = 0;
        for (float value : array) {
            if (!predicate.test(value)) {
                newArray[index++] = value;
            }
        }

        return newArray;
    }

    /**
     * 从数组中移除所有指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static int[] removeAll(int[] array, int element) {
        return removeAll(array, value -> value == element);
    }

    /**
     * 移除数组中所有符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static int[] removeAll(int[] array, IntPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 统计不等于目标元素的个数
        int count = 0;
        for (int value : array) {
            if (!predicate.test(value)) {
                count++;
            }
        }

        // 没有要移除的元素
        if (count == array.length) {
            return clone(array);
        }

        // 创建新数组
        int[] newArray = new int[count];
        int index = 0;
        for (int value : array) {
            if (!predicate.test(value)) {
                newArray[index++] = value;
            }
        }

        return newArray;
    }

    /**
     * 从数组中移除所有指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static long[] removeAll(long[] array, long element) {
        return removeAll(array, value -> value == element);
    }

    /**
     * 移除数组中所有符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static long[] removeAll(long[] array, LongPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 统计不等于目标元素的个数
        int count = 0;
        for (long value : array) {
            if (!predicate.test(value)) {
                count++;
            }
        }

        // 没有要移除的元素
        if (count == array.length) {
            return clone(array);
        }

        // 创建新数组
        long[] newArray = new long[count];
        int index = 0;
        for (long value : array) {
            if (!predicate.test(value)) {
                newArray[index++] = value;
            }
        }

        return newArray;
    }

    /**
     * 从数组中移除所有指定的元素
     *
     * @param array   数组
     * @param element 要移除的元素
     * @return 新数组
     */
    public static short[] removeAll(short[] array, short element) {
        return removeAll(array, value -> value == element);
    }

    /**
     * 移除数组中所有符合条件的元素
     *
     * @param array     数组
     * @param predicate 判断函数
     * @return 新数组
     */
    public static short[] removeAll(short[] array, ShortPredicate predicate) {
        // 处理空数组
        if (isEmpty(array)) {
            return clone(array);
        }

        // 统计不等于目标元素的个数
        int count = 0;
        for (short value : array) {
            if (!predicate.test(value)) {
                count++;
            }
        }

        // 没有要移除的元素
        if (count == array.length) {
            return clone(array);
        }

        // 创建新数组
        short[] newArray = new short[count];
        int index = 0;
        for (short value : array) {
            if (!predicate.test(value)) {
                newArray[index++] = value;
            }
        }

        return newArray;
    }

    /**
     * 反转数组
     *
     * @param array 数组
     * @return 反转后的新数组
     */
    public static <T> T[] reverse(T[] array) {
        return reverse(array, 0);
    }

    /**
     * 反转数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4) = [0, 1, 2, 6, 5, 4, 3]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  99) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99) = [6, 5, 4, 3, 2, 1, 0]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 反转后的新数组
     */
    public static <T> T[] reverse(T[] array, int startIndex) {
        return reverse(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 反转数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1,  4) = [0, 3, 2, 1, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4, -1) = [0, 1, 2, 5, 4, 3, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   2,  2) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -1, -3) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1, 99) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99,  4) = [3, 2, 1, 0, 4, 5, 6]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引(不包含)
     * @return 反转后的新数组
     */
    public static <T> T[] reverse(T[] array, int startIndex, int endIndex) {
        T[] newArray = clone(array);
        if (isEmpty(newArray)) {
            return newArray;
        }

        int length = newArray.length;

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = startIndex + length;
        }
        if (endIndex < 0) {
            endIndex = endIndex + length;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, length) - 1;

        while (endIndex > startIndex) {
            doSwap(newArray, startIndex++, endIndex--);
        }

        return newArray;
    }

    /**
     * 反转数组
     *
     * @param array 数组
     * @return 反转后的新数组
     */
    public static boolean[] reverse(boolean[] array) {
        return reverse(array, 0);
    }

    /**
     * 反转数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4) = [0, 1, 2, 6, 5, 4, 3]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  99) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99) = [6, 5, 4, 3, 2, 1, 0]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 反转后的新数组
     */
    public static boolean[] reverse(boolean[] array, int startIndex) {
        return reverse(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 反转数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1,  4) = [0, 3, 2, 1, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4, -1) = [0, 1, 2, 5, 4, 3, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   2,  2) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -1, -3) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1, 99) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99,  4) = [3, 2, 1, 0, 4, 5, 6]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引(不包含)
     * @return 反转后的新数组
     */
    public static boolean[] reverse(boolean[] array, int startIndex, int endIndex) {
        boolean[] newArray = clone(array);
        if (isEmpty(newArray)) {
            return newArray;
        }

        int length = newArray.length;

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, length) - 1;

        while (endIndex > startIndex) {
            doSwap(newArray, startIndex++, endIndex--);
        }

        return newArray;
    }

    /**
     * 反转数组
     *
     * @param array 数组
     * @return 反转后的新数组
     */
    public static byte[] reverse(byte[] array) {
        return reverse(array, 0);
    }

    /**
     * 反转数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4) = [0, 1, 2, 6, 5, 4, 3]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  99) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99) = [6, 5, 4, 3, 2, 1, 0]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 反转后的新数组
     */
    public static byte[] reverse(byte[] array, int startIndex) {
        return reverse(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 反转数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1,  4) = [0, 3, 2, 1, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4, -1) = [0, 1, 2, 5, 4, 3, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   2,  2) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -1, -3) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1, 99) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99,  4) = [3, 2, 1, 0, 4, 5, 6]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引(不包含)
     * @return 反转后的新数组
     */
    public static byte[] reverse(byte[] array, int startIndex, int endIndex) {
        byte[] newArray = clone(array);
        if (isEmpty(newArray)) {
            return newArray;
        }

        int length = newArray.length;

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, length) - 1;

        while (endIndex > startIndex) {
            doSwap(newArray, startIndex++, endIndex--);
        }

        return newArray;
    }

    /**
     * 反转数组
     *
     * @param array 数组
     * @return 反转后的新数组
     */
    public static char[] reverse(char[] array) {
        return reverse(array, 0);
    }

    /**
     * 反转数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4) = [0, 1, 2, 6, 5, 4, 3]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  99) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99) = [6, 5, 4, 3, 2, 1, 0]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 反转后的新数组
     */
    public static char[] reverse(char[] array, int startIndex) {
        return reverse(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 反转数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1,  4) = [0, 3, 2, 1, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4, -1) = [0, 1, 2, 5, 4, 3, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   2,  2) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -1, -3) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1, 99) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99,  4) = [3, 2, 1, 0, 4, 5, 6]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引(不包含)
     * @return 反转后的新数组
     */
    public static char[] reverse(char[] array, int startIndex, int endIndex) {
        char[] newArray = clone(array);
        if (isEmpty(newArray)) {
            return newArray;
        }

        int length = newArray.length;

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, length) - 1;

        while (endIndex > startIndex) {
            doSwap(newArray, startIndex++, endIndex--);
        }

        return newArray;
    }

    /**
     * 反转数组
     *
     * @param array 数组
     * @return 反转后的新数组
     */
    public static double[] reverse(double[] array) {
        return reverse(array, 0);
    }

    /**
     * 反转数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4) = [0, 1, 2, 6, 5, 4, 3]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  99) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99) = [6, 5, 4, 3, 2, 1, 0]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 反转后的新数组
     */
    public static double[] reverse(double[] array, int startIndex) {
        return reverse(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 反转数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1,  4) = [0, 3, 2, 1, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4, -1) = [0, 1, 2, 5, 4, 3, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   2,  2) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -1, -3) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1, 99) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99,  4) = [3, 2, 1, 0, 4, 5, 6]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引(不包含)
     * @return 反转后的新数组
     */
    public static double[] reverse(double[] array, int startIndex, int endIndex) {
        double[] newArray = clone(array);
        if (isEmpty(newArray)) {
            return newArray;
        }

        int length = newArray.length;

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, length) - 1;

        while (endIndex > startIndex) {
            doSwap(newArray, startIndex++, endIndex--);
        }

        return newArray;
    }

    /**
     * 反转数组
     *
     * @param array 数组
     * @return 反转后的新数组
     */
    public static float[] reverse(float[] array) {
        return reverse(array, 0);
    }

    /**
     * 反转数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4) = [0, 1, 2, 6, 5, 4, 3]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  99) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99) = [6, 5, 4, 3, 2, 1, 0]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 反转后的新数组
     */
    public static float[] reverse(float[] array, int startIndex) {
        return reverse(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 反转数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1,  4) = [0, 3, 2, 1, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4, -1) = [0, 1, 2, 5, 4, 3, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   2,  2) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -1, -3) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1, 99) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99,  4) = [3, 2, 1, 0, 4, 5, 6]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引(不包含)
     * @return 反转后的新数组
     */
    public static float[] reverse(float[] array, int startIndex, int endIndex) {
        float[] newArray = clone(array);
        if (isEmpty(newArray)) {
            return newArray;
        }

        int length = newArray.length;

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, length) - 1;

        while (endIndex > startIndex) {
            doSwap(newArray, startIndex++, endIndex--);
        }

        return newArray;
    }

    /**
     * 反转数组
     *
     * @param array 数组
     * @return 反转后的新数组
     */
    public static int[] reverse(int[] array) {
        return reverse(array, 0);
    }

    /**
     * 反转数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4) = [0, 1, 2, 6, 5, 4, 3]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  99) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99) = [6, 5, 4, 3, 2, 1, 0]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 反转后的新数组
     */
    public static int[] reverse(int[] array, int startIndex) {
        return reverse(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 反转数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1,  4) = [0, 3, 2, 1, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4, -1) = [0, 1, 2, 5, 4, 3, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   2,  2) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -1, -3) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1, 99) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99,  4) = [3, 2, 1, 0, 4, 5, 6]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引(不包含)
     * @return 反转后的新数组
     */
    public static int[] reverse(int[] array, int startIndex, int endIndex) {
        int[] newArray = clone(array);
        if (isEmpty(newArray)) {
            return newArray;
        }

        int length = newArray.length;

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, length) - 1;

        while (endIndex > startIndex) {
            doSwap(newArray, startIndex++, endIndex--);
        }

        return newArray;
    }

    /**
     * 反转数组
     *
     * @param array 数组
     * @return 反转后的新数组
     */
    public static long[] reverse(long[] array) {
        return reverse(array, 0);
    }

    /**
     * 反转数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4) = [0, 1, 2, 6, 5, 4, 3]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  99) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99) = [6, 5, 4, 3, 2, 1, 0]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 反转后的新数组
     */
    public static long[] reverse(long[] array, int startIndex) {
        return reverse(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 反转数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1,  4) = [0, 3, 2, 1, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4, -1) = [0, 1, 2, 5, 4, 3, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   2,  2) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -1, -3) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1, 99) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99,  4) = [3, 2, 1, 0, 4, 5, 6]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引(不包含)
     * @return 反转后的新数组
     */
    public static long[] reverse(long[] array, int startIndex, int endIndex) {
        long[] newArray = clone(array);
        if (isEmpty(newArray)) {
            return newArray;
        }

        int length = newArray.length;

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, length) - 1;

        while (endIndex > startIndex) {
            doSwap(newArray, startIndex++, endIndex--);
        }

        return newArray;
    }

    /**
     * 反转数组
     *
     * @param array 数组
     * @return 反转后的新数组
     */
    public static short[] reverse(short[] array) {
        return reverse(array, 0);
    }

    /**
     * 反转数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4) = [0, 1, 2, 6, 5, 4, 3]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  99) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99) = [6, 5, 4, 3, 2, 1, 0]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 反转后的新数组
     */
    public static short[] reverse(short[] array, int startIndex) {
        return reverse(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 反转数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与反转效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1,  4) = [0, 3, 2, 1, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -4, -1) = [0, 1, 2, 5, 4, 3, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   2,  2) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},  -1, -3) = [0, 1, 2, 3, 4, 5, 6]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6},   1, 99) = [0, 6, 5, 4, 3, 2, 1]
     * ArrayUtil.reverse(new int[]{0, 1, 2, 3, 4, 5, 6}, -99,  4) = [3, 2, 1, 0, 4, 5, 6]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引(不包含)
     * @return 反转后的新数组
     */
    public static short[] reverse(short[] array, int startIndex, int endIndex) {
        short[] newArray = clone(array);
        if (isEmpty(newArray)) {
            return newArray;
        }

        int length = newArray.length;

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, length) - 1;

        while (endIndex > startIndex) {
            doSwap(newArray, startIndex++, endIndex--);
        }

        return newArray;
    }

    /**
     * 打乱数组
     *
     * @param array 数组
     * @return 打乱后的新数组
     */
    public static <T> T[] shuffle(T[] array) {
        return shuffle(array, new Random());
    }

    /**
     * 打乱数组
     *
     * @param array  数组
     * @param random 随机数生成器
     * @return 打乱后的新数组
     */
    public static <T> T[] shuffle(T[] array, Random random) {
        T[] newArray = clone(array);
        for (int i = array.length; i > 1; i--) {
            doSwap(array, i - 1, random.nextInt(i));
        }
        return newArray;
    }

    /**
     * 打乱数组
     *
     * @param array 数组
     * @return 打乱后的新数组
     */
    public static boolean[] shuffle(boolean[] array) {
        return shuffle(array, new Random());
    }

    /**
     * 打乱数组
     *
     * @param array  数组
     * @param random 随机数生成器
     * @return 打乱后的新数组
     */
    public static boolean[] shuffle(boolean[] array, Random random) {
        boolean[] newArray = clone(array);
        if (isNotEmpty(newArray)) {
            for (int i = newArray.length - 1; i > 0; i--) {
                doSwap(newArray, i, random.nextInt(i + 1));
            }
        }
        return newArray;
    }

    /**
     * 打乱数组
     *
     * @param array 数组
     * @return 打乱后的新数组
     */
    public static byte[] shuffle(byte[] array) {
        return shuffle(array, new Random());
    }

    /**
     * 打乱数组
     *
     * @param array  数组
     * @param random 随机数生成器
     * @return 打乱后的新数组
     */
    public static byte[] shuffle(byte[] array, Random random) {
        byte[] newArray = clone(array);
        if (isNotEmpty(newArray)) {
            for (int i = newArray.length - 1; i > 0; i--) {
                doSwap(newArray, i, random.nextInt(i + 1));
            }
        }
        return newArray;
    }

    /**
     * 打乱数组
     *
     * @param array 数组
     * @return 打乱后的新数组
     */
    public static char[] shuffle(char[] array) {
        return shuffle(array, new Random());
    }

    /**
     * 打乱数组
     *
     * @param array  数组
     * @param random 随机数生成器
     * @return 打乱后的新数组
     */
    public static char[] shuffle(char[] array, Random random) {
        char[] newArray = clone(array);
        if (isNotEmpty(newArray)) {
            for (int i = newArray.length - 1; i > 0; i--) {
                doSwap(newArray, i, random.nextInt(i + 1));
            }
        }
        return newArray;
    }

    /**
     * 打乱数组
     *
     * @param array 数组
     * @return 打乱后的新数组
     */
    public static double[] shuffle(double[] array) {
        return shuffle(array, new Random());
    }

    /**
     * 打乱数组
     *
     * @param array  数组
     * @param random 随机数生成器
     * @return 打乱后的新数组
     */
    public static double[] shuffle(double[] array, Random random) {
        double[] newArray = clone(array);
        if (isNotEmpty(newArray)) {
            for (int i = newArray.length - 1; i > 0; i--) {
                doSwap(newArray, i, random.nextInt(i + 1));
            }
        }
        return newArray;
    }

    /**
     * 打乱数组
     *
     * @param array 数组
     * @return 打乱后的新数组
     */
    public static float[] shuffle(float[] array) {
        return shuffle(array, new Random());
    }

    /**
     * 打乱数组
     *
     * @param array  数组
     * @param random 随机数生成器
     * @return 打乱后的新数组
     */
    public static float[] shuffle(float[] array, Random random) {
        float[] newArray = clone(array);
        if (isNotEmpty(newArray)) {
            for (int i = newArray.length - 1; i > 0; i--) {
                doSwap(newArray, i, random.nextInt(i + 1));
            }
        }
        return newArray;
    }

    /**
     * 打乱数组
     *
     * @param array 数组
     * @return 打乱后的新数组
     */
    public static int[] shuffle(int[] array) {
        return shuffle(array, new Random());
    }

    /**
     * 打乱数组
     *
     * @param array  数组
     * @param random 随机数生成器
     * @return 打乱后的新数组
     */
    public static int[] shuffle(int[] array, Random random) {
        int[] newArray = clone(array);
        if (isNotEmpty(newArray)) {
            for (int i = newArray.length - 1; i > 0; i--) {
                doSwap(newArray, i, random.nextInt(i + 1));
            }
        }
        return newArray;
    }

    /**
     * 打乱数组
     *
     * @param array 数组
     * @return 打乱后的新数组
     */
    public static long[] shuffle(long[] array) {
        return shuffle(array, new Random());
    }

    /**
     * 打乱数组
     *
     * @param array  数组
     * @param random 随机数生成器
     * @return 打乱后的新数组
     */
    public static long[] shuffle(long[] array, Random random) {
        long[] newArray = clone(array);
        if (isNotEmpty(newArray)) {
            for (int i = newArray.length - 1; i > 0; i--) {
                doSwap(newArray, i, random.nextInt(i + 1));
            }
        }
        return newArray;
    }

    /**
     * 打乱数组
     *
     * @param array 数组
     * @return 打乱后的新数组
     */
    public static short[] shuffle(short[] array) {
        return shuffle(array, new Random());
    }

    /**
     * 打乱数组
     *
     * @param array  数组
     * @param random 随机数生成器
     * @return 打乱后的新数组
     */
    public static short[] shuffle(short[] array, Random random) {
        short[] newArray = clone(array);
        if (isNotEmpty(newArray)) {
            for (int i = newArray.length - 1; i > 0; i--) {
                doSwap(newArray, i, random.nextInt(i + 1));
            }
        }
        return newArray;
    }

    /**
     * 截取数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3) = [2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  99) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99) = [0, 1, 2, 3, 4]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 截取的新数组
     */
    public static <T> T[] subarray(T[] array, int startIndex) {
        return subarray(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 截取数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1,  3) = [1, 2]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3, -1) = [2, 3]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   2,  2) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -1, -3) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1, 99) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99,  3) = [0, 1, 2]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引索引(不包含)
     * @return 截取的新数组
     */
    @SuppressWarnings("unchecked")
    public static <T> T[] subarray(T[] array, int startIndex, int endIndex) {
        if (isEmpty(array)) {
            return clone(array);
        }

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = array.length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = array.length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, array.length);

        int newLength = endIndex - startIndex;
        if (newLength <= 0) {
            return (T[]) EMPTY_OBJECT_ARRAY;
        }

        Class<?> type = array.getClass().getComponentType();
        T[] newArray = (T[]) Array.newInstance(type, newLength);
        System.arraycopy(array, startIndex, newArray, 0, newLength);

        return newArray;
    }

    /**
     * 截取数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3) = [2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  99) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99) = [0, 1, 2, 3, 4]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 截取的新数组
     */
    public static boolean[] subarray(boolean[] array, int startIndex) {
        return subarray(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 截取数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1,  3) = [1, 2]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3, -1) = [2, 3]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   2,  2) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -1, -3) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1, 99) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99,  3) = [0, 1, 2]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引索引(不包含)
     * @return 截取的新数组
     */
    public static boolean[] subarray(boolean[] array, int startIndex, int endIndex) {
        if (isEmpty(array)) {
            return clone(array);
        }

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = startIndex + array.length;
        }
        if (endIndex < 0) {
            endIndex = endIndex + array.length;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, array.length);

        int newLength = endIndex - startIndex;
        if (newLength <= 0) {
            return EMPTY_BOOLEAN_ARRAY;
        }

        boolean[] newArray = new boolean[newLength];
        System.arraycopy(array, startIndex, newArray, 0, newLength);

        return newArray;
    }

    /**
     * 截取数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3) = [2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  99) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99) = [0, 1, 2, 3, 4]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 截取的新数组
     */
    public static byte[] subarray(byte[] array, int startIndex) {
        return subarray(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 截取数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1,  3) = [1, 2]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3, -1) = [2, 3]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   2,  2) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -1, -3) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1, 99) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99,  3) = [0, 1, 2]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引索引(不包含)
     * @return 截取的新数组
     */
    public static byte[] subarray(byte[] array, int startIndex, int endIndex) {
        if (isEmpty(array)) {
            return clone(array);
        }

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = array.length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = array.length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, array.length);

        int newLength = endIndex - startIndex;
        if (newLength <= 0) {
            return EMPTY_BYTE_ARRAY;
        }

        byte[] newArray = new byte[newLength];
        System.arraycopy(array, startIndex, newArray, 0, newLength);

        return newArray;
    }

    /**
     * 截取数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3) = [2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  99) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99) = [0, 1, 2, 3, 4]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 截取的新数组
     */
    public static char[] subarray(char[] array, int startIndex) {
        return subarray(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 截取数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1,  3) = [1, 2]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3, -1) = [2, 3]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   2,  2) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -1, -3) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1, 99) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99,  3) = [0, 1, 2]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引索引(不包含)
     * @return 截取的新数组
     */
    public static char[] subarray(char[] array, int startIndex, int endIndex) {
        if (isEmpty(array)) {
            return clone(array);
        }

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = array.length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = array.length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, array.length);

        int newLength = endIndex - startIndex;
        if (newLength <= 0) {
            return EMPTY_CHAR_ARRAY;
        }

        char[] newArray = new char[newLength];
        System.arraycopy(array, startIndex, newArray, 0, newLength);

        return newArray;
    }

    /**
     * 截取数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3) = [2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  99) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99) = [0, 1, 2, 3, 4]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 截取的新数组
     */
    public static double[] subarray(double[] array, int startIndex) {
        return subarray(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 截取数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1,  3) = [1, 2]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3, -1) = [2, 3]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   2,  2) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -1, -3) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1, 99) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99,  3) = [0, 1, 2]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引索引(不包含)
     * @return 截取的新数组
     */
    public static double[] subarray(double[] array, int startIndex, int endIndex) {
        if (isEmpty(array)) {
            return clone(array);
        }

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = array.length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = array.length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, array.length);

        int newLength = endIndex - startIndex;
        if (newLength <= 0) {
            return EMPTY_DOUBLE_ARRAY;
        }

        double[] newArray = new double[newLength];
        System.arraycopy(array, startIndex, newArray, 0, newLength);

        return newArray;
    }

    /**
     * 截取数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3) = [2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  99) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99) = [0, 1, 2, 3, 4]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 截取的新数组
     */
    public static float[] subarray(float[] array, int startIndex) {
        return subarray(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 截取数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1,  3) = [1, 2]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3, -1) = [2, 3]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   2,  2) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -1, -3) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1, 99) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99,  3) = [0, 1, 2]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引索引(不包含)
     * @return 截取的新数组
     */
    public static float[] subarray(float[] array, int startIndex, int endIndex) {
        if (isEmpty(array)) {
            return clone(array);
        }

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = array.length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = array.length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, array.length);

        int newLength = endIndex - startIndex;
        if (newLength <= 0) {
            return EMPTY_FLOAT_ARRAY;
        }

        float[] newArray = new float[newLength];
        System.arraycopy(array, startIndex, newArray, 0, newLength);

        return newArray;
    }

    /**
     * 截取数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3) = [2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  99) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99) = [0, 1, 2, 3, 4]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 截取的新数组
     */
    public static int[] subarray(int[] array, int startIndex) {
        return subarray(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 截取数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1,  3) = [1, 2]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3, -1) = [2, 3]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   2,  2) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -1, -3) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1, 99) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99,  3) = [0, 1, 2]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引索引(不包含)
     * @return 截取的新数组
     */
    public static int[] subarray(int[] array, int startIndex, int endIndex) {
        if (isEmpty(array)) {
            return clone(array);
        }

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = array.length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = array.length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, array.length);

        int newLength = endIndex - startIndex;
        if (newLength <= 0) {
            return EMPTY_INT_ARRAY;
        }

        int[] newArray = new int[newLength];
        System.arraycopy(array, startIndex, newArray, 0, newLength);

        return newArray;
    }

    /**
     * 截取数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3) = [2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  99) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99) = [0, 1, 2, 3, 4]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 截取的新数组
     */
    public static long[] subarray(long[] array, int startIndex) {
        return subarray(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 截取数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1,  3) = [1, 2]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3, -1) = [2, 3]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   2,  2) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -1, -3) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1, 99) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99,  3) = [0, 1, 2]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引索引(不包含)
     * @return 截取的新数组
     */
    public static long[] subarray(long[] array, int startIndex, int endIndex) {
        if (isEmpty(array)) {
            return clone(array);
        }

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = array.length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = array.length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, array.length);

        int newLength = endIndex - startIndex;
        if (newLength <= 0) {
            return EMPTY_LONG_ARRAY;
        }

        long[] newArray = new long[newLength];
        System.arraycopy(array, startIndex, newArray, 0, newLength);

        return newArray;
    }

    /**
     * 截取数组中从 {@code startIndex} 到末尾的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3) = [2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  99) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99) = [0, 1, 2, 3, 4]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @return 截取的新数组
     */
    public static short[] subarray(short[] array, int startIndex) {
        return subarray(array, startIndex, Integer.MAX_VALUE);
    }

    /**
     * 截取数组中从 {@code startIndex} 到 {@code endIndex} 的元素
     *
     * <p>
     * 负数索引表示从数组末尾开始计算索引，
     * 如：{@code -1} 表示最后一个元素，{@code -2} 表示倒数第二个元素，
     * {@code -n} 表示倒数第 {@code n} 个元素，以此类推。
     *
     * <p>
     * 示例（为展示索引与截取效果，统一使用 {@code int[]} 数据）：
     * <blockquote><pre>
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1,  3) = [1, 2]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -3, -1) = [2, 3]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   2,  2) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},  -1, -3) = []
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4},   1, 99) = [1, 2, 3, 4]
     * ArrayUtil.subarray(new int[]{0, 1, 2, 3, 4}, -99,  3) = [0, 1, 2]
     * </pre></blockquote>
     *
     * @param array      数组
     * @param startIndex 起始位置索引
     * @param endIndex   结束位置索引索引(不包含)
     * @return 截取的新数组
     */
    public static short[] subarray(short[] array, int startIndex, int endIndex) {
        if (isEmpty(array)) {
            return clone(array);
        }

        // 处理负数索引
        if (startIndex < 0) {
            startIndex = array.length + startIndex;
        }
        if (endIndex < 0) {
            endIndex = array.length + endIndex;
        }

        // 约束索引
        startIndex = Math.max(startIndex, 0);
        endIndex = Math.min(endIndex, array.length);

        int newLength = endIndex - startIndex;
        if (newLength <= 0) {
            return EMPTY_SHORT_ARRAY;
        }

        short[] newArray = new short[newLength];
        System.arraycopy(array, startIndex, newArray, 0, newLength);

        return newArray;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     * @return 交换元素后的新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static <T> T[] swap(T[] array, int index1, int index2) {
        T[] newArray = clone(array);
        if (index1 == index2 || isEmpty(newArray)) {
            return newArray;
        }

        Objects.checkIndex(index1, array.length);
        Objects.checkIndex(index2, array.length);

        doSwap(newArray, index1, index2);

        return newArray;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     * @return 交换元素后的新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static boolean[] swap(boolean[] array, int index1, int index2) {
        boolean[] newArray = clone(array);
        if (index1 == index2 || isEmpty(newArray)) {
            return newArray;
        }

        Objects.checkIndex(index1, array.length);
        Objects.checkIndex(index2, array.length);

        doSwap(newArray, index1, index2);

        return newArray;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     * @return 交换元素后的新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static byte[] swap(byte[] array, int index1, int index2) {
        byte[] newArray = clone(array);
        if (index1 == index2 || isEmpty(newArray)) {
            return newArray;
        }

        Objects.checkIndex(index1, array.length);
        Objects.checkIndex(index2, array.length);

        doSwap(newArray, index1, index2);

        return newArray;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     * @return 交换元素后的新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static char[] swap(char[] array, int index1, int index2) {
        char[] newArray = clone(array);
        if (index1 == index2 || isEmpty(newArray)) {
            return newArray;
        }

        Objects.checkIndex(index1, array.length);
        Objects.checkIndex(index2, array.length);

        doSwap(newArray, index1, index2);

        return newArray;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     * @return 交换元素后的新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static double[] swap(double[] array, int index1, int index2) {
        double[] newArray = clone(array);
        if (index1 == index2 || isEmpty(newArray)) {
            return newArray;
        }

        Objects.checkIndex(index1, array.length);
        Objects.checkIndex(index2, array.length);

        doSwap(newArray, index1, index2);

        return newArray;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     * @return 交换元素后的新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static float[] swap(float[] array, int index1, int index2) {
        float[] newArray = clone(array);
        if (index1 == index2 || isEmpty(newArray)) {
            return newArray;
        }

        Objects.checkIndex(index1, array.length);
        Objects.checkIndex(index2, array.length);

        doSwap(newArray, index1, index2);

        return newArray;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     * @return 交换元素后的新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static int[] swap(int[] array, int index1, int index2) {
        int[] newArray = clone(array);
        if (index1 == index2 || isEmpty(newArray)) {
            return newArray;
        }

        Objects.checkIndex(index1, array.length);
        Objects.checkIndex(index2, array.length);

        doSwap(newArray, index1, index2);

        return newArray;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     * @return 交换元素后的新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static long[] swap(long[] array, int index1, int index2) {
        long[] newArray = clone(array);
        if (index1 == index2 || isEmpty(newArray)) {
            return newArray;
        }

        Objects.checkIndex(index1, array.length);
        Objects.checkIndex(index2, array.length);

        doSwap(newArray, index1, index2);

        return newArray;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     * @return 交换元素后的新数组
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    public static short[] swap(short[] array, int index1, int index2) {
        short[] newArray = clone(array);
        if (index1 == index2 || isEmpty(newArray)) {
            return newArray;
        }

        Objects.checkIndex(index1, array.length);
        Objects.checkIndex(index2, array.length);

        doSwap(newArray, index1, index2);

        return newArray;
    }

    /**
     * 将数组转为 {@code List}
     *
     * @param array 数组
     * @return 返回一个 {@link ArrayList} ，如果 {@code array} 为 {@code null}，则返回 {@code null}
     */
    public static <T> List<T> toList(T[] array) {
        return array == null ? null : new ArrayList<>(Arrays.asList(array));
    }

    /**
     * 将数组转为 {@code List}
     *
     * @param array 数组
     * @return 返回一个 {@link ArrayList} ，如果 {@code array} 为 {@code null}，则返回 {@code null}
     */
    public static List<Boolean> toList(boolean[] array) {
        return toList(toObject(array));
    }

    /**
     * 将数组转为 {@code List}
     *
     * @param array 数组
     * @return 返回一个 {@link ArrayList} ，如果 {@code array} 为 {@code null}，则返回 {@code null}
     */
    public static List<Byte> toList(byte[] array) {
        return toList(toObject(array));
    }

    /**
     * 将数组转为 {@code List}
     *
     * @param array 数组
     * @return 返回一个 {@link ArrayList} ，如果 {@code array} 为 {@code null}，则返回 {@code null}
     */
    public static List<Character> toList(char[] array) {
        return toList(toObject(array));
    }

    /**
     * 将数组转为 {@code List}
     *
     * @param array 数组
     * @return List
     */
    public static List<Double> toList(double[] array) {
        return toList(toObject(array));
    }

    /**
     * 将数组转为 {@code List}
     *
     * @param array 数组
     * @return 返回一个 {@link ArrayList} ，如果 {@code array} 为 {@code null}，则返回 {@code null}
     */
    public static List<Float> toList(float[] array) {
        return toList(toObject(array));
    }

    /**
     * 将数组转为 {@code List}
     *
     * @param array 数组
     * @return 返回一个 {@link ArrayList} ，如果 {@code array} 为 {@code null}，则返回 {@code null}
     */
    public static List<Integer> toList(int[] array) {
        return toList(toObject(array));
    }

    /**
     * 将数组转为 {@code List}
     *
     * @param array 数组
     * @return 返回一个 {@link ArrayList} ，如果 {@code array} 为 {@code null}，则返回 {@code null}
     */
    public static List<Long> toList(long[] array) {
        return toList(toObject(array));
    }

    /**
     * 将数组转为 {@code List}
     *
     * @param array 数组
     * @return 返回一个 {@link ArrayList} ，如果 {@code array} 为 {@code null}，则返回 {@code null}
     */
    public static List<Short> toList(short[] array) {
        return toList(toObject(array));
    }

    /**
     * 原始类型数组转为包装类型数组
     *
     * @param array 原始类型数组
     * @return 包装类型数组
     */
    public static Boolean[] toObject(boolean[] array) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_BOOLEAN_OBJECT_ARRAY;
        }

        return map(array, Boolean::valueOf);
    }

    /**
     * 原始类型数组转为包装类型数组
     *
     * @param array 原始类型数组
     * @return 包装类型数组
     */
    public static Byte[] toObject(byte[] array) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_BYTE_OBJECT_ARRAY;
        }

        return map(array, Byte::valueOf);
    }

    /**
     * 原始类型数组转为包装类型数组
     *
     * @param array 原始类型数组
     * @return 包装类型数组
     */
    public static Character[] toObject(char[] array) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_CHARACTER_OBJECT_ARRAY;
        }

        return map(array, Character::valueOf);
    }

    /**
     * 原始类型数组转为包装类型数组
     *
     * @param array 原始类型数组
     * @return 包装类型数组
     */
    public static Double[] toObject(double[] array) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_DOUBLE_OBJECT_ARRAY;
        }

        return map(array, Double::valueOf);
    }

    /**
     * 原始类型数组转为包装类型数组
     *
     * @param array 原始类型数组
     * @return 包装类型数组
     */
    public static Float[] toObject(float[] array) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_FLOAT_OBJECT_ARRAY;
        }

        return map(array, Float::valueOf);
    }

    /**
     * 原始类型数组转为包装类型数组
     *
     * @param array 原始类型数组
     * @return 包装类型数组
     */
    public static Integer[] toObject(int[] array) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_INTEGER_OBJECT_ARRAY;
        }

        return map(array, Integer::valueOf);
    }

    /**
     * 原始类型数组转为包装类型数组
     *
     * @param array 原始类型数组
     * @return 包装类型数组
     */
    public static Long[] toObject(long[] array) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_LONG_OBJECT_ARRAY;
        }

        return map(array, Long::valueOf);
    }

    /**
     * 原始类型数组转为包装类型数组
     *
     * @param array 原始类型数组
     * @return 包装类型数组
     */
    public static Short[] toObject(short[] array) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_SHORT_OBJECT_ARRAY;
        }

        return map(array, Short::valueOf);
    }

    /**
     * 包装类型数组转为原始类型数组
     *
     * @param array 包装类型数组
     * @return 原始类型数组
     */
    public static boolean[] toPrimitive(Boolean[] array, boolean valueForNull) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_BOOLEAN_ARRAY;
        }

        boolean[] newArray = new boolean[array.length];

        for (int i = 0; i < array.length; ++i) {
            Boolean value = array[i];
            newArray[i] = value != null ? value : valueForNull;
        }

        return newArray;
    }

    /**
     * 包装类型数组转为原始类型数组
     *
     * @param array 包装类型数组
     * @return 原始类型数组
     */
    public static byte[] toPrimitive(Byte[] array, byte valueForNull) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_BYTE_ARRAY;
        }

        byte[] newArray = new byte[array.length];

        for (int i = 0; i < array.length; ++i) {
            Byte value = array[i];
            newArray[i] = value != null ? value : valueForNull;
        }

        return newArray;
    }

    /**
     * 包装类型数组转为原始类型数组
     *
     * @param array 包装类型数组
     * @return 原始类型数组
     */
    public static char[] toPrimitive(Character[] array, char valueForNull) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_CHAR_ARRAY;
        }

        char[] newArray = new char[array.length];

        for (int i = 0; i < array.length; ++i) {
            Character value = array[i];
            newArray[i] = value != null ? value : valueForNull;
        }

        return newArray;
    }

    /**
     * 包装类型数组转为原始类型数组
     *
     * @param array 包装类型数组
     * @return 原始类型数组
     */
    public static double[] toPrimitive(Double[] array, double valueForNull) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_DOUBLE_ARRAY;
        }

        double[] newArray = new double[array.length];

        for (int i = 0; i < array.length; ++i) {
            Double value = array[i];
            newArray[i] = value != null ? value : valueForNull;
        }

        return newArray;
    }

    /**
     * 包装类型数组转为原始类型数组
     *
     * @param array 包装类型数组
     * @return 原始类型数组
     */
    public static float[] toPrimitive(Float[] array, float valueForNull) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_FLOAT_ARRAY;
        }

        float[] newArray = new float[array.length];

        for (int i = 0; i < array.length; ++i) {
            Float value = array[i];
            newArray[i] = value != null ? value : valueForNull;
        }

        return newArray;
    }

    /**
     * 包装类型数组转为原始类型数组
     *
     * @param array 包装类型数组
     * @return 原始类型数组
     */
    public static int[] toPrimitive(Integer[] array, int valueForNull) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_INT_ARRAY;
        }

        int[] newArray = new int[array.length];

        for (int i = 0; i < array.length; ++i) {
            Integer value = array[i];
            newArray[i] = value != null ? value : valueForNull;
        }

        return newArray;
    }

    /**
     * 包装类型数组转为原始类型数组
     *
     * @param array 包装类型数组
     * @return 原始类型数组
     */
    public static long[] toPrimitive(Long[] array, long valueForNull) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_LONG_ARRAY;
        }

        long[] newArray = new long[array.length];

        for (int i = 0; i < array.length; ++i) {
            Long value = array[i];
            newArray[i] = value != null ? value : valueForNull;
        }

        return newArray;
    }

    /**
     * 包装类型数组转为原始类型数组
     *
     * @param array 包装类型数组
     * @return 原始类型数组
     */
    public static short[] toPrimitive(Short[] array, short valueForNull) {
        if (array == null) {
            return null;
        }

        if (array.length == 0) {
            return EMPTY_SHORT_ARRAY;
        }

        short[] newArray = new short[array.length];

        for (int i = 0; i < array.length; ++i) {
            Short value = array[i];
            newArray[i] = value != null ? value : valueForNull;
        }

        return newArray;
    }

    /**
     * 对数组的每个元素应用指定的转换函数，并返回包含结果的新数组
     *
     * @param array    数组
     * @param function 转换函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <T, R> R[] map(T[] array, SFunction<? super T, R> function) {
        if (array == null) {
            return null;
        }

        checkMapFunction(function);

        R[] newArray = (R[]) Array.newInstance(function.getReturnType(), array.length);
        for (int i = 0; i < array.length; i++) {
            newArray[i] = function.apply(array[i]);
        }

        return newArray;
    }

    /**
     * 对数组的每个元素应用指定的转换函数，并返回包含结果的新数组
     *
     * @param array    数组
     * @param function 转换函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <R> R[] map(boolean[] array, BooleanSFunction<R> function) {
        checkMapFunction(function);

        if (array == null) {
            return null;
        }

        R[] newArray = (R[]) Array.newInstance(function.getReturnType(), array.length);
        for (int i = 0; i < array.length; i++) {
            newArray[i] = function.apply(array[i]);
        }

        return newArray;
    }

    /**
     * 对数组的每个元素应用指定的转换函数，并返回包含结果的新数组
     *
     * @param array    数组
     * @param function 转换函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <R> R[] map(byte[] array, ByteSFunction<R> function) {
        checkMapFunction(function);

        if (array == null) {
            return null;
        }

        R[] newArray = (R[]) Array.newInstance(function.getReturnType(), array.length);
        for (int i = 0; i < array.length; i++) {
            newArray[i] = function.apply(array[i]);
        }

        return newArray;
    }

    /**
     * 对数组的每个元素应用指定的转换函数，并返回包含结果的新数组
     *
     * @param array    数组
     * @param function 函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <R> R[] map(char[] array, CharSFunction<R> function) {
        checkMapFunction(function);

        if (array == null) {
            return null;
        }

        R[] newArray = (R[]) Array.newInstance(function.getReturnType(), array.length);
        for (int i = 0; i < array.length; i++) {
            newArray[i] = function.apply(array[i]);
        }

        return newArray;
    }

    /**
     * 对数组的每个元素应用指定的转换函数，并返回包含结果的新数组
     *
     * @param array    数组
     * @param function 转换函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <R> R[] map(double[] array, DoubleSFunction<R> function) {
        checkMapFunction(function);

        if (array == null) {
            return null;
        }

        R[] newArray = (R[]) Array.newInstance(function.getReturnType(), array.length);
        for (int i = 0; i < array.length; i++) {
            newArray[i] = function.apply(array[i]);
        }

        return newArray;
    }

    /**
     * 对数组的每个元素应用指定的转换函数，并返回包含结果的新数组
     *
     * @param array    数组
     * @param function 转换函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <R> R[] map(float[] array, FloatSFunction<R> function) {
        checkMapFunction(function);

        if (array == null) {
            return null;
        }

        R[] newArray = (R[]) Array.newInstance(function.getReturnType(), array.length);
        for (int i = 0; i < array.length; i++) {
            newArray[i] = function.apply(array[i]);
        }

        return newArray;
    }

    /**
     * 对数组的每个元素应用指定的转换函数，并返回包含结果的新数组
     *
     * @param array    数组
     * @param function 转换函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <R> R[] map(int[] array, IntSFunction<R> function) {
        checkMapFunction(function);

        if (array == null) {
            return null;
        }

        R[] newArray = (R[]) Array.newInstance(function.getReturnType(), array.length);
        for (int i = 0; i < array.length; i++) {
            newArray[i] = function.apply(array[i]);
        }
        return newArray;
    }

    /**
     * 对数组的每个元素应用指定的转换函数，并返回包含结果的新数组
     *
     * @param array    数组
     * @param function 转换函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <R> R[] map(long[] array, LongSFunction<R> function) {
        checkMapFunction(function);

        if (array == null) {
            return null;
        }

        R[] newArray = (R[]) Array.newInstance(function.getReturnType(), array.length);
        for (int i = 0; i < array.length; i++) {
            newArray[i] = function.apply(array[i]);
        }
        return newArray;
    }

    /**
     * 对数组的每个元素应用指定的转换函数，并返回包含结果的新数组
     *
     * @param array    数组
     * @param function 转换函数
     * @return 新数组
     */
    @SuppressWarnings("unchecked")
    public static <R> R[] map(short[] array, ShortSFunction<R> function) {
        checkMapFunction(function);

        if (array == null) {
            return null;
        }

        R[] newArray = (R[]) Array.newInstance(function.getReturnType(), array.length);
        for (int i = 0; i < array.length; i++) {
            newArray[i] = function.apply(array[i]);
        }
        return newArray;
    }

    /**
     * 判断索引是否有效
     *
     * @param array 数组
     * @param index 索引
     * @return boolean
     */
    public static boolean isValidIndex(Object array, int index) {
        return index >= 0 && index < getLength(array);
    }

    /**
     * 获取数组长度
     *
     * @param array 数组
     * @return 长度
     */
    public static int getLength(Object array) {
        return array == null ? 0 : Array.getLength(array);
    }

    /**
     * 检查插入索引是否有效
     *
     * @param index  索引
     * @param length 长度
     * @throws IndexOutOfBoundsException 索引越界时抛出
     */
    private static void checkInsertIndex(int index, int length) {
        // 插入时如果数组长度为0，则索引允许任意值
        if (length == 0) {
            return;
        }
        Objects.checkIndex(index, length);
    }

    /**
     * 检查转换函数
     *
     * @param function 转换函数
     */
    private static void checkMapFunction(SerializableLambda<?> function) {
        Assert.notNull(function, "Map function must not be null");
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     */
    private static <T> void doSwap(T[] array, int index1, int index2) {
        T temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     */
    private static void doSwap(boolean[] array, int index1, int index2) {
        boolean temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     */
    private static void doSwap(byte[] array, int index1, int index2) {
        byte temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     */
    private static void doSwap(char[] array, int index1, int index2) {
        char temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     */
    private static void doSwap(double[] array, int index1, int index2) {
        double temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     */
    private static void doSwap(float[] array, int index1, int index2) {
        float temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     */
    private static void doSwap(int[] array, int index1, int index2) {
        int temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     */
    private static void doSwap(long[] array, int index1, int index2) {
        long temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

    /**
     * 交换数组元素
     *
     * @param array  数组
     * @param index1 索引1
     * @param index2 索引2
     */
    private static void doSwap(short[] array, int index1, int index2) {
        short temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }

}
